Almost finish parser

This commit is contained in:
Danila Fedorin 2019-05-12 19:01:25 -07:00
parent 51b20b280d
commit 3b2f6baff9

108
parser.y
View File

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