%{ #include #include #include #define OVECCOUNT 3 int yylex (void); void yyerror (char const *); int regex_cmp(char* s, char* r); %} %union { int b; int n; char* str; } %token CONST %token REGEX %token ERR %token NUM %token VAR %token KW_IF KW_ELSE KW_PIPE KW_MAIL KW_COPY %token '(' ')' '{' '}' %left ARROW %left EQ NEQ GE LE '<' '>' RE NRE %left '+' '-' %left '*' '/' %left '|' '&' '^' %left '!' %left '=' %type boo %% input: /* empty */ | input line ; line: '\n' | boo '\n' { printf("%s\n",$1?"true":"false"); } | error '\n' { yyerrok; } ; boo: CONST EQ CONST { $$ = ! strcmp($1, $3); } | CONST NEQ CONST { $$ = !! strcmp($1, $3); } | CONST RE REGEX { $$ = regex_cmp($1,$3) >= 0 } | CONST NRE REGEX { $$ = regex_cmp($1,$3) < 0 } | NUM EQ NUM { $$ = $1 == $3 } | NUM NEQ NUM { $$ = $1 != $3 } | NUM GE NUM { $$ = $1 >= $3 } | NUM LE NUM { $$ = $1 <= $3 } | NUM '>' NUM { $$ = $1 > $3 } | NUM '<' NUM { $$ = $1 < $3 } | boo '|' boo { $$ = $1 || $3 } | boo '&' boo { $$ = $1 && $3 } | boo '^' boo { $$ = ($1 || $3) && !($1 && $3) } | '!' boo { $$ = ! $2 } ; ; %% #include #include #define BUFSIZE 4096 int regex_cmp(char* s, char* r) { pcre *brum; int erroroffset; const char* error; int ovector[OVECCOUNT]; brum=pcre_compile(r,0,&error,&erroroffset,NULL); if (!brum) return -1; int res=pcre_exec(brum,NULL,s,strlen(s),0,0,ovector,OVECCOUNT); pcre_free(brum); return res; } char* get_string_out(char delim) { int last = delim; int i = 0; char* s; int c; if (!(s = malloc(BUFSIZE))){ puts("Low memory"); exit(0); } while ((c = getchar()) != delim || last == '\\'){ if (last=='\\' && c != delim) s[i-1] = c; else { s[i] = c; i++; } last = c; if (i >= BUFSIZE-1) break; } s[i] = '\0'; return s; } int safe_unget(char c) { if (c==EOF) return 0; ungetc(c,stdin); return 1; } int yylex(void) { int c, last; while ((c = getchar ()) == ' ' || c == '\t'); if (c == '"'){ last = '"'; yylval.str = get_string_out('"'); return CONST; } if (c == '\''){ last = '\''; yylval.str = get_string_out('\''); return CONST; } if (c == '/'){ last = '/'; yylval.str = get_string_out('/'); return REGEX; } if (isdigit(c)){ ungetc(c,stdin); scanf("%d",&yylval.n); return NUM; } if (c == '!'){ if ((c = getchar ()) == '=') return NEQ; else if (c == '~') return NRE; else { safe_unget(c); return '!'; } } if (c == '<'){ if ((c = getchar ()) == '=') return LE; else { safe_unget(c); return '<'; } } if (c == '>'){ if ((c = getchar ()) == '=') return GE; else { safe_unget(c); return '>'; } } if (c == '='){ if ((c = getchar ()) == '=') return EQ; else { safe_unget(c); return '='; } } if (c == '~'){ if ((c = getchar ()) == '~') return RE; else { safe_unget(c); return ERR; } } if (c == '-'){ if ((c = getchar ()) == '>') return ARROW; else { safe_unget(c); return '-'; } } if (c == '$'){ int i=0; if (!(yylval.str=malloc(BUFSIZE))){ puts("Low memory"); exit (0); } while (isalnum(c = getchar()) || c == '_' || c == '-'){ yylval.str[i]=c; i++; if (i >= BUFSIZE) break; } return VAR; } if (c == '\n' || c == '+' || c == '*' || c == '/' || c == '(' || c == ')' || c == '{' || c == '}') return c; #define KLEN 10 if (isalpha(c)){ char buf[KLEN]; int i=0; ungetc(c,stdin); while (isalpha(c = getchar()) && i