%{ #include #include int yylex (void); void yyerror (char const *); %} %union { int b; int n; char* str; } %token CONST %token NUM %left EQ NEQ GE LE GT LT %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); } | NUM EQ NUM { $$ = $1 == $3 } | NUM NEQ NUM { $$ = $1 != $3 } | NUM GE NUM { $$ = $1 >= $3 } | NUM LE NUM { $$ = $1 <= $3 } | NUM GT NUM { $$ = $1 > $3 } | NUM LT 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 yylex(void) { int i, c, last; while ((c = getchar ()) == ' ' || c == '\t'); if (c == '"'){ last = '"'; i = 0; if (!(yylval.str = malloc(BUFSIZE))){ puts("Low memory"); exit(0); } while ((c = getchar()) != '"' || last == '\\'){ yylval.str[i] = c; last = c; i++; if (i >= BUFSIZE-1) break; } yylval.str[i] = '\0'; return CONST; } if (isdigit(c)){ ungetc(c,stdin); scanf("%d",&yylval.n); return NUM; } if (c == '!'){ if ((c = getchar ()) == '=') return NEQ; } if (c == '<'){ if ((c = getchar ()) == '=') return LE; else return LT; } if (c == '>'){ if ((c = getchar ()) == '=') return GE; else return GT; } if (c == '='){ if ((c = getchar ()) == '=') return EQ; } if (c == EOF) return 0; return c; } void yyerror (char const *s) { fprintf (stderr, "%s\n", s); } int main(void) { return yyparse (); }