/* SI 413 Fall 2011
* Lab 6
* spl-pt1.ypp
* Parser for SPL that just shows the parse tree
*/
%{
#include <cstdlib>
#include <iostream>
using namespace std;
#include "parsetree.hpp"
ParseTree* tree; // This global will be set to the whole parse tree.
int yylex();
int yyerror(const char *p) { cerr << "Parse error!" << endl; }
%}
%token LC RC LP RP NUM BOOL ID LAMBDA IF WHILE READ WRITE NEW STOP ASN ELSE
%token BOP NOT COMP OPA OPM
%%
/*Note: YYACCEPT is a bison macro that just tells it to quit parsing.*/
res: block { tree = $1; YYACCEPT; }
| stmt { tree = $1; YYACCEPT; }
| { tree = NULL; }
block: LC stmtlist RC { $$ = new ParseTree("block",$2); }
stmtlist: stmtlist stmt { $$ = new ParseTree("stmtlist",$1,$2); }
| stmt { $$ = new ParseTree("stmtlist",$1); }
stmt: NEW ID ASN exp STOP {$$ = new ParseTree("stmt",$1,$2,$3,$4,$5);}
| ID ASN exp STOP {$$ = new ParseTree("stmt",$1,$2,$3,$4);}
| READ ID STOP {$$ = new ParseTree("stmt",$1,$2,$3);}
| WRITE exp STOP {$$ = new ParseTree("stmt",$1,$2,$3);}
| IF LP exp RP block {$$ = new ParseTree("stmt",$1,$2,$3,$4,$5);}
| IF LP exp RP block ELSE block {$$ = new ParseTree
("stmt",$1,$2,$3,$4,$5,$6,$7);
}
| WHILE LP exp RP block {$$ = new ParseTree("stmt",$1,$2,$3,$4,$5);}
| exp STOP {$$ = new ParseTree("stmt",$1,$2);}
exp: exp BOP nexp {$$ = new ParseTree("exp",$1,$2,$3);}
| nexp {$$ = new ParseTree("exp",$1);}
nexp: NOT cexp {$$ = new ParseTree("nexp",$1,$2);}
| cexp {$$ = new ParseTree("nexp",$1);}
cexp: cexp COMP aexp {$$ = new ParseTree("cexp",$1,$2,$3);}
| aexp {$$ = new ParseTree("cexp",$1);}
aexp: aexp OPA term {$$ = new ParseTree("aexp",$1,$2,$3);}
| term {$$ = new ParseTree("aexp",$1);}
term: term OPM sfactor {$$ = new ParseTree("term",$1,$2,$3);}
| sfactor {$$ = new ParseTree("term",$1);}
sfactor: OPA factor {$$ = new ParseTree("sfactor",$1,$2);}
| factor {$$ = new ParseTree("sfactor",$1);}
factor: ID | NUM | BOOL {$$ = new ParseTree("factor",$1);}
| LP exp RP {$$ = new ParseTree("factor",$1,$2,$3);}
| ID LP exp RP {$$ = new ParseTree("factor",$1,$2,$3,$4);}
| LAMBDA ID block {$$ = new ParseTree("factor",$1,$2,$3);}
%%
int main()
{
while(true) {
yyparse();
if (tree == NULL) break;
tree->writeDot("spl1.dot");
system("dot -Tpdf spl1.dot > spl1.pdf");
system("evince spl1.pdf &");
}
return 0;
}