/* Reverse polish notation calculator using Bison's semantic parser option. */ %{ /* Must define the following: */ #if 0 yyrecover yymsg yyabort timeclock #endif #include #ifndef YYLTYPE struct mytype { clock_t timestamp; int first_line, last_line, first_column, last_column; char* text; }; typedef struct mytype mytype; #define YYLTYPE mytype #endif #define YYSTYPE double #include int yylex(); #define YYABORT return -1 #define YYACCEPT return 0 %} %semantic_parser %token NUM %% input: /* empty */ | input line ; line: '\n' | exp '\n' { printf ("\t%.10g\n", \$1); } ; exp: NUM { \$\$ = \$1; } | exp exp '+' { \$\$ = \$1 + \$2; } | exp exp '-' { \$\$ = \$1 - \$2; } | exp exp '*' { \$\$ = \$1 * \$2; } | exp exp '/' { \$\$ = \$1 / \$2; } /* Exponentiation */ | exp exp '^' { \$\$ = pow (\$1, \$2); } /* Unary minus */ | exp 'n' { \$\$ = -\$1; } ; %% /* 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 #include int 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; } #if __MWERKS__ && macintosh #include #endif int timeclock; char * yymsg = "I'm not feeling right.\n"; int main() { #if __MWERKS__ && macintosh SIOUXSettings.asktosaveonclose = 0; SIOUXSettings.autocloseonquit = 0; #endif timeclock = clock(); return yyparse(); } int yyrecover() { } int yyabort(char* errstr) { printf("Error: %s\n", errstr); return EXIT_SUCCESS; } #if 0 int yyerror(char* errstr) { printf("Error: %s\n", errstr); printf("(Exit)\n"); exit(EXIT_FAILURE); return EXIT_SUCCESS; } #endif