%token ID ASSIGNMENT WHILE DO AND OR LE GE EQ NE TYPE %left OR %left AND %right NE EQ %nonassoc GE LE '>' '<' %right '!' %left '+' %left '*' '/' %right '-' %{ #include "generator.h" struct STableValue { Type type; }; map gSymbolTable; int gTmpPlaceNumber = 0; int gLabelNumber = 0; void newtmp( string& place ); void newlabel( string& label ); %} %% superprogram: program { cout << $1.code; } ; program: program statement ';' { $$.code = $1.code + $2.code; } | statement ';' { $$.code = $1.code; } ; statement: WHILE expression DO statement { newlabel( $$.begin ); newlabel( $$.after ); $$.code = $$.begin + ":\n" + $2.code + "if " + $2.place + " = 0 goto " + $$.after + '\n' + $4.code + "goto " + $$.begin + '\n' + $$.after + ":\n"; } | ID ASSIGNMENT expression { $$.code = $3.code + $1.place + " := " + $3.place + '\n'; } | TYPE ID { $$.code = ""; STableValue val; if( gSymbolTable.find($2.place) == gSymbolTable.end() ) { val.type = $1.type; gSymbolTable[$2.place] = val; } else { cerr << "Dude, you redeclared " << $2.place << endl; } } ; expression: expression '+' expression { newtmp( $$.place ); $$.code = $1.code + $3.code + $$.place + " := " + $1.place + " + " + $3.place + '\n'; } | expression '*' expression { newtmp( $$.place ); $$.code = $1.code + $3.code + $$.place + " := " + $1.place + " * " + $3.place + '\n'; } | '-' expression { newtmp( $$.place ); $$.code = $2.code + $$.place + " := uminus " + $2.place + '\n'; } | '(' expression ')' { $$.place = $2.place; $$.code = $2.code; } | expression AND expression { newtmp( $$.place); $$.code = $1.code + $3.code + $$.place + " := " + $1.place + " && " + $3.place + '\n'; } | expression OR expression { newtmp( $$.place); $$.code = $1.code + $3.code + $$.place + " := " + $1.place + " || " + $3.place + '\n'; } | expression NE expression { newtmp( $$.place); $$.code = $1.code + $3.code + $$.place + " := " + $1.place + " != " + $3.place + '\n'; } | expression EQ expression { newtmp( $$.place); $$.code = $1.code + $3.code + $$.place + " := " + $1.place + " == " + $3.place + '\n'; } | expression GE expression { newtmp( $$.place); $$.code = $1.code + $3.code + $$.place + " := " + $1.place + " >= " + $3.place + '\n'; } | expression LE expression { newtmp( $$.place); $$.code = $1.code + $3.code + $$.place + " := " + $1.place + " <= " + $3.place + '\n'; } | expression '<' expression { newtmp( $$.place); $$.code = $1.code + $3.code + $$.place + " := " + $1.place + " < " + $3.place + '\n'; } | expression '>' expression { newtmp( $$.place); $$.code = $1.code + $3.code + $$.place + " := " + $1.place + " > " + $3.place + '\n'; } | '!' expression { newtmp( $$.place); $$.code = $2.code + $$.place + " := " + " ! " + $2.place + '\n'; } | ID { $$.place = $1.place; $$.code = ""; } ; %% void newtmp( string& place ) { char str[20]; sprintf( str, "t%d", gTmpPlaceNumber ); place = str; gTmpPlaceNumber++; } void newlabel( string& label ) { char str[20]; sprintf( str, "L%d", gLabelNumber ); label = str; gLabelNumber++; }