/* Reverse polish notation calculator. calc1a.y */ /* Hand-coded lexer rather than flex-generated. */ /* Right-recursive production for sequence of */ /* expressions. What is the consequence? */ %{ #define YYSTYPE double #include %} %token NUM %% input : '\n' | exp '\n' { printf ("\t= %.2f\n", $1); } | exp '\n' input { printf ("\t= %.2f\n", $1); } ; exp : NUM { $$ = $1; } | exp exp '+' { $$ = $1 + $2; } | exp exp '-' { $$ = $1 - $2; } | exp exp '*' { $$ = $1 * $2; } | exp exp '/' { $$ = $1 / $2; } | exp exp '^' { $$ = pow ($1, $2); } | exp 'n' { $$ = -$1; } /* Unary negation */ ; %% /* Lexical analyzer returns a double floating point number on the stack and the token NUM, or the ASCII character read if not a number. Skips all blanks and tabs, returns 0 for EOF. */ #include yylex () { int c; /* skip white space */ while ((c = getchar ()) == ' ' || c == '\t') ; /* process numbers */ if (c == '.' || isdigit (c)) { ungetc (c, stdin); scanf ("%lf", &yylval); return NUM; } /* return end-of-file */ if (c == EOF) return 0; /* return single chars */ return c; } main () { yyparse (); } #include yyerror (char *s) /* Called by yyparse on error */ { printf ("\terror: %s\n", s); }