/* calculator.y Jeff Ondich, 5/30/10 Bison example, based on several found on-line, especially http://www.cs.ucr.edu/~lgao/teaching/calc/calc.y by Lan Gao. This is the file that specifies the grammar we are applying to our input strings, and what actions to take each time a non-terminal constituent is recognized by the parser. */ %{ #include "calculator.h" %} /* The %union construct defines the type of the yylval variable (as a C/C++ union). In this example, the lexer will set the value of yylval.value whenever it recognizes a token, and the parser will get access to yylval.value via the $$, $1, $2, $3, etc. variables. */ %union{ int value; } /* You set the start symbol, terminals (tokens), and nonterminals (types) for your grammar here. Different tokens and types could have different yylval types if the %union had more than one option listed. In this example, all our tokens and types have integer values using the variable yylval.value. */ %start input %token INTEGER %type expression /* A couple notes on %left and %right: 1. %left and %right refer to the type of associativity to use with the named operator. So "%left SUB" (if you were doing subtraction) would indicate that "10 - 3 - 2" should be 5. But "%right SUB" would mean that "10 - 3 - 2" would be 9. 2. The order in which you place %left and %right directives in your code determines the precedence of those operators. Try playing around with order. 3. "%left PLUS SUB" would say that PLUS and SUB have the same precedence. */ %left PLUS %left MULT %% input: /* empty */ | expression { cout << "Result: " << $1 << endl; } ; expression: INTEGER { $$ = $1; } | expression PLUS expression { $$ = $1 + $3; } | expression MULT expression { $$ = $1 * $3; } ; %% int yyerror(const string& s) { extern char *yytext; // defined and maintained in lex.c cerr << s << " at symbol \"" << yytext << "\"" << endl; exit(1); } int yyerror(char *s) { return yyerror(string(s)); }