/* * bison specification for infix calculator. * Compile as follows: * $ yacc -d exp.y * output: y.tab.c and y.tab.h * $ bison -d exp.y * output: exp.tab.c and exp.tab.h * $ bison -y -d exp.y * same as yacc -d exp.y */ %{ #include int yylex (void); /* type of yylex() */ void yyerror(char const *s); #define YYDEBUG 1 /* enables compilation with trace facility */ %} %union { /* type of 'yylval' (stack type) */ int integer ; /* type name is YYSTYPE */ float real ; /* default #define YYSTYPE int ple type */ } %token INT FLOAT /* tokens and types */ %type exp /* nonterminal and its type */ /* lower-case by convention */ %left '-' '+' /* left associative character */ %left '*' '/' /* tokens: 'nonassoc', 'right' */ %left UNEG UPOS /* precedence of unary + - */ /* + - lowest precedence */ /* * / next higher */ /* unary + i highest */ %start s /* start symbol */ %% /* Grammar rules and action follows */ s: s line | /* Empty string */ ; line: '\n' | exp '\n' { printf("%f\n", $1) ; } | error '\n' { yyerrok ; } ; /* 'error' is a reserve word and yyerrok() * is a macro defined by Bison */ exp: INT { $$ = (float)$1; } | FLOAT /* Default action */ | exp '+' exp { $$ = $1 + $3 ; } | exp '-' exp { $$ = $1 - $3 ; } | exp '*' exp { $$ = $1 * $3 ; } | exp '/' exp { if($3 == 0) yyerror("Divide by zeroi"); else $$ = $1 / $3 ; } | '-' exp %prec UNEG { $$ = - $2 ; } /* Context dependent */ | '+' exp %prec UPOS { $$ = $2 ; } /* precedence */ | '(' exp ')' { $$ = $2 ; } ; %% int main() { // yydebug = 1 ; To get trace information return yyparse() ; } /* * called by yyparse() on error */ void yyerror(char const *s) {fprintf(stderr, "%s\n", s);}