%{ #define YYDEBUG 1 #include #include %} /* YACC Declarations */ %token NUM %left '-' '+' %left '*' '/' %left NEG /* negation--unary minus */ %right '^' /* exponentiation */ /* Grammar follows */ %% input: /* empty string */ | input line ; line: '\n' | exp '\n' { printf("%d\n", $1); } ; exp: NUM { $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | '-' exp %prec NEG { $$ = -$2; } | exp '^' exp { $$ = pow($1, $3);} | '(' exp ')' { $$ = $2; } ; %% static char line[1024]; int advance(int n) { int i; for (i=n; line[i]; i++) line[i-n] = line[i]; line[i-n] = line[i]; } int yylex() { int tok; static int token_char; if (!strcmp(line, "")) { if (fgets(line, 1024, stdin) == NULL) { return -1; } } switch (line[0]) { case '\n': { advance(1); return '\n'; } case ' ': case '\t': { advance(1); return yylex(); } case '+': case '-': case '*': case '/': case '^': case '(': case ')': { int rv = line[0]; advance(1); return rv; } case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '.': { yylval = atoi(line); while (isdigit(line[0]) || (line[0]=='.')) advance(1); return NUM; } } } int yyerror(char *s) { fprintf(stderr, "%s\n", s); fflush(stderr); } int main() { // yydebug = 1; yyparse(); }