/* Reverse polish notation calculator. calc1.y */ /* Hand-coded lexer rather than flex-generated. */ %{ #define YYSTYPE double #include #include #include %} %token NUM %% input : /* empty */ | input line ; line : '\n' | exp '\n' { 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. */ 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 (); } yyerror (char *s) /* Called by yyparse on error */ { printf ("\terror: %s\n", s); }