/********************************************************
* calc.ypp
* SI 413 Fall 2011
* Lab 3
* Bison file specifying the calculator program parser
*
* YOUR NAME HERE
* YOUR PARTNER'S NAME HERE
********************************************************/
%{
#include <iostream>
#include <string>
#include <map>
#include <cstdlib> //-- I need this for atoi
using namespace std;
//-- Lexer prototype required by bison, aka getNextToken()
int yylex();
int yyerror(const char *p) { cerr << "Parse error!" << endl; }
%}
//-- SYMBOL SEMANTIC VALUES -----------------------------
//-- In bison, every symbol, whether it be token or non-terminal
//-- can have a "semantic value". A NUM token "4.35", has
//-- semantic value 4.35. A "term" symbol representing
//-- "-3.5*2*5" has semantic value 35.0, which you get by
//-- evaluating -3.5*2*5. An OPA symbol's semantic value
//-- is '+' or '-' depending on which symbol we actually read.
//-- Some tokens, like STOP or RP don't need a semantic value.
//-- The %union statement lists the type-and-name for each
//-- semantic value. The %token and %type statements let you
//-- you specify semantic value types for tokens and
//-- non-terminals.
%union {
int val;
char sym;
};
%token <val> NUM
%token <sym> OPA OPM LP RP STOP
%type <val> exp term sfactor factor res
//-- GRAMMAR RULES ---------------------------------------
%%
run: res run | res /* forces bison to process many stmts */
res: exp STOP { cout << $1 << endl; }
exp: exp OPA term { $$ = ($2 == '+' ? $1 + $3 : $1 - $3); }
| term { $$ = $1; }
term: term OPM factor { $$ = ($2 == '*' ? $1 * $3 : $1 / $3); }
| sfactor { $$ = $1; }
sfactor: OPA factor { $$ = ($1 == '+' ? $2 : -$2); }
| factor { $$ = $1; }
factor: NUM { $$ = $1; }
| LP exp RP { $$ = $2; }
%%
//-- FUNCTION DEFINITIONS ---------------------------------
int main()
{
yyparse();
return 0;
}