/* SI 413 Fall 2011
* Lab 6
* spl-pt2.ypp
* Parser for SPL that just shows the parse tree
* This parser uses a simpler grammar with assoc/prec specifications.
*/
%{
#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; }
%}
%left BOP
%right NOT
%left COMP
%left OPA
%left OPM
%right POSNEG
%nonassoc LC RC LP RP NUM BOOL ID LAMBDA IF ELSE WHILE READ WRITE NEW STOP ASN
%%
/*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 exp {$$ = new ParseTree("exp",$1,$2,$3);}
| NOT exp {$$ = new ParseTree("exp",$1,$2);}
| exp COMP exp {$$ = new ParseTree("exp",$1,$2,$3);}
| exp OPA exp {$$ = new ParseTree("exp",$1,$2,$3);}
| exp OPM exp {$$ = new ParseTree("exp",$1,$2,$3);}
| OPA exp %prec POSNEG {$$ = new ParseTree("exp",$1,$2);}
| LAMBDA ID block {$$ = new ParseTree("exp",$1,$2,$3);}
| ID LP exp RP {$$ = new ParseTree("exp",$1,$2,$3,$4);}
| LP exp RP {$$ = new ParseTree("exp",$1,$2,$3);}
| ID {$$ = new ParseTree("exp",$1);}
| NUM {$$ = new ParseTree("exp",$1);}
| BOOL {$$ = new ParseTree("exp",$1);}
%%
int main()
{
while(true) {
yyparse();
if (tree == NULL) break;
tree->writeDot("spl2.dot");
system("dot -Tpdf spl2.dot > spl2.pdf");
system("evince spl2.pdf &");
}
return 0;
}