diff --git a/parser.y b/parser.y index 9a18155..86a3147 100644 --- a/parser.y +++ b/parser.y @@ -41,13 +41,37 @@ %token COMMA %token COLON -%define api.value.type { const char* } +%define api.value.type { std::string* } %define api.pure full %define api.push-pull push %start program %{ +template ::value, T>::type* = nullptr> +void concat(std::string* s, T vs) { + s->append(vs); +} + +template ::value, T>::type* = nullptr> +void concat(std::string* s, T vs) { + s->append(*vs); + delete vs; +} + +template +void concat(std::string* s, T v, Ts ... vs) { + concat(s, v); + concat(s, vs...); +} + +template +std::string* concatenate(Ts ... vs) { + std::string* temp = new std::string(); + concat(temp, vs...); + return temp; +} + void yyerror(const char* s) { std::cout << s << std::endl; } @@ -59,80 +83,88 @@ std::set varset; %% program - : stmts + : stmts { std::cout << *$1 << std::endl; $$ = $1; } ; stmts - : stmts stmt - | stmt + : stmts stmt { $$ = concatenate($1, $2); } + | stmt { $$ = $1; } ; stmt - : expr NEWLINE - | if - | while - | BREAK NEWLINE + : expr NEWLINE { $$ = concatenate($1, ";"); } + | if { $$ = $1; } + | while { $$ = $1; } + | BREAK NEWLINE { $$ = new std::string("break;"); } ; expr - : assign - | eq + : assign { $$ = $1; } + | eq { $$ = $1; } ; while - : WHILE expr COLON NEWLINE block + : WHILE expr COLON NEWLINE block { $$ = concatenate("while(", $2, ")", $5); } ; if - : IF expr COLON NEWLINE block ifend - | IF expr COLON NEWLINE block + : IF expr COLON NEWLINE block elses { $$ = concatenate("if(", $2, ")", $5, $6); } ; -ifend - : ELIF expr COLON NEWLINE block ifend - | ELIF expr COLON NEWLINE block - | ELSE COLON NEWLINE block +elses + : %empty { $$ = new std::string(""); } + | elif elses { $$ = concatenate($1, $2); } + | else { $$ = $1; } + ; + +elif + : ELIF expr COLON NEWLINE block { $$ = concatenate("else if(", $2, ")", $5); } + ; + +else + : ELSE COLON NEWLINE block { $$ = concatenate("else", $4); } + ; block - : INDENT stmts DEDENT + : INDENT stmts DEDENT { $$ = concatenate("{", $2, "}"); } ; assign - : IDENTIFIER ASSIGN expr + : IDENTIFIER ASSIGN expr { varset.insert(*$1); $$ = concatenate($1, "=", $3); } ; eq - : eq EQ rel - | eq NEQ rel - | rel + : eq EQ rel { $$ = concatenate($1, "==", $3); } + | eq NEQ rel { $$ = concatenate($1, "!=", $3); } + | rel { $$ = $1; } ; rel - : rel LT sum - | rel LTE sum - | rel GT sum - | rel GTE sum - | sum + : rel LT sum { $$ = concatenate($1, "<", $3); } + | rel LTE sum { $$ = concatenate($1, "<=", $3); } + | rel GT sum { $$ = concatenate($1, ">", $3); } + | rel GTE sum { $$ = concatenate($1, ">=", $3); } + | sum { $$ = $1; } ; sum - : sum PLUS factor - | sum MINUS factor - | factor + : sum PLUS factor { $$ = concatenate($1, "+", $3); } + | sum MINUS factor { $$ = concatenate($1, "-", $3); } + | factor { $$ = $1; } ; factor - : factor TIMES term - | factor DIVIDEDBY term - | term + : factor TIMES term { $$ = concatenate($1, "*", $3); } + | factor DIVIDEDBY term { $$ = concatenate($1, "/", $3); } + | term { $$ = $1; } ; term - : IDENTIFIER - | FLOAT - | INTEGER - | BOOLEAN - | LPAREN expr RPAREN + : IDENTIFIER { $$ = $1; } + | FLOAT { $$ = $1; } + | INTEGER { $$ = $1; } + | BOOLEAN { $$ = $1; } + | LPAREN expr RPAREN { $$ = $2; } ; %%