-
Notifications
You must be signed in to change notification settings - Fork 1
/
parser.yacc
198 lines (166 loc) · 6.91 KB
/
parser.yacc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
%{
#include "node.h"
NBlock* programBlock; /* the top level root node of our final AST */
extern int yylex();
void yyerror(const char *s) { printf("ERROR: %s\n", s); }
%}
/* Represents the many different ways we can access our data */
%union {
Node* node;
NBlock* block;
NExpression* expr;
NStatement* stmt;
NIdentifier* ident;
NVariableDeclaration* var_decl;
NIterator* iter;
std::vector<NVariableDeclaration*>* varvec;
std::vector<NExpression*>* exprvec;
std::string* string;
int token;
}
/* Define our terminal symbols (tokens). This should
match our tokens.l lex file. We also define the node type
they represent.
*/
%token <string> TIDENTIFIER TINTEGER TCSTSTRING // TDOUBLE
%token <token> TTRUE TFALSE
%token <token> TCEQ TCNE TCLT TCLE TCGT TCGE TEQUAL
%token <token> TLPAREN TRPAREN TLBRACE TRBRACE TLBRACK TRBRACK TLLBRACK TRRBRACK TCOMMA TDOT TCOLON TSCOLON
%token <token> TPLUS TMINUS TMUL TDIV TMOD TPOW
%token <token> TIF TELSE TFN TWHILE TFOR TIN TRET TBREAK TCONTINUE TRANGE
%token <token> TRARROW
/* Define the type of node our nonterminal symbols represent.
The types refer to the %union declaration above. Ex: when
we call an ident (defined by union type ident) we are really
calling an (NIdentifier*). It makes the compiler happy.
*/
%type <ident> ident
%type <expr> cst_int expr cst_string binop
%type <varvec> func_decl_args
%type <exprvec> call_args type
%type <block> program stmts block
%type <stmt> stmt func_decl if_stmt for_stmt while_stmt ret_stmt break_stmt continue_stmt
%type <iter> iterator
%type <var_decl> var_decl simple_var_decl
%start program
/* Operator precedence for mathematical operators */
%left TCEQ TCNE TCLT TCLE TCGT TCGE
%left TPLUS TMINUS
%left TMUL TDIV TMOD
%right TPOW
%left TLBRACK TRBRACK TLLBRACK TRRBRACK
%left TLPAREN TRPAREN
%%
program : stmts { programBlock = $1; }
;
stmts : stmt { $$ = new NBlock(); $$->statements.push_back($1); }
| stmts stmt { $1->statements.push_back($2); }
;
stmt : var_decl TSCOLON { $$ = (NStatement*)$1; }
| func_decl
| expr TSCOLON { $$ = new NExpressionStatement(*$1); }
| if_stmt
| for_stmt
| while_stmt
| ret_stmt TSCOLON
| break_stmt TSCOLON
| continue_stmt TSCOLON
;
if_stmt : TIF expr TCOLON block { $$ = new NIfStatement($2, $4); }
| TIF expr TCOLON stmt
{ auto tbl = new NBlock();
tbl->statements.push_back($4);
$$ = new NIfStatement($2, tbl); }
| TIF expr TCOLON block TELSE TCOLON block { $$ = new NIfStatement($2, $4, $7); }
| TIF expr TCOLON stmt TELSE TCOLON block
{ auto tbl = new NBlock();
tbl->statements.push_back($4);
$$ = new NIfStatement($2, tbl, $7); }
| TIF expr TCOLON block TELSE TCOLON stmt
{ auto tbl = new NBlock();
tbl->statements.push_back($7);
$$ = new NIfStatement($2, $4, tbl); }
| TIF expr TCOLON stmt TELSE TCOLON stmt
{ auto tbl1 = new NBlock();
tbl1->statements.push_back($4);
auto tbl2 = new NBlock();
tbl2->statements.push_back($7);
$$ = new NIfStatement($2, tbl1, tbl2); }
;
iterator : TRANGE TLPAREN expr TRPAREN { $$ = new NRangeIterator(0, $3);}
| TRANGE TLPAREN expr TCOMMA expr TRPAREN { $$ = new NRangeIterator($3, $5);}
| TRANGE TLPAREN expr TCOMMA expr TCOMMA expr TRPAREN { $$ = new NRangeIterator($3, $5, $7);}
| TLLBRACK expr TCOMMA expr TRRBRACK { $$ = new NRangeIterator($2, $4, nullptr, true);}
;
for_stmt : TFOR simple_var_decl TIN iterator TCOLON block { $$ = new NForStatement($2, $4, $6); }
| TFOR simple_var_decl TIN iterator TCOLON stmt
{ auto tbl = new NBlock();
tbl->statements.push_back($6);
$$ = new NForStatement($2, $4, tbl); }
;
while_stmt : TWHILE expr TCOLON block { $$ = new NWhileStatement($2, $4); }
| TWHILE expr TCOLON stmt
{ auto tbl = new NBlock();
tbl->statements.push_back($4);
$$ = new NWhileStatement($2, tbl); }
;
break_stmt : TBREAK {$$ = new NBreakStatement();}
;
continue_stmt : TCONTINUE {$$ = new NContinueStatement();}
;
ret_stmt : TRET {$$ = new NReturnStatement();}
| TRET expr {$$ = new NReturnStatement($2);}
;
block : TLBRACE stmts TRBRACE { $$ = $2; }
| TLBRACE TRBRACE { $$ = new NBlock(); }
;
type : ident { $$ = new ExpressionList(); $$->push_back($1); }
| type TRARROW ident { $$->push_back($3); }
;
simple_var_decl : ident TCOLON type { $$ = new NVariableDeclaration(*$3, *$1); }
;
var_decl : ident TCOLON type TEQUAL expr { $$ = new NVariableDeclaration(*$3, *$1, $5); }
| simple_var_decl
;
func_decl : TFN ident TLPAREN func_decl_args TRPAREN TCOLON type block
{ $$ = new NFunctionDeclaration($7, *$2, *$4, *$8); delete $4; }
;
func_decl_args : /*blank*/ { $$ = new VariableList(); }
| var_decl { $$ = new VariableList(); $$->push_back($1); }
| func_decl_args TCOMMA var_decl { $1->push_back($3); }
;
ident : TIDENTIFIER { $$ = new NIdentifier(*$1); delete $1; }
;
cst_string : TCSTSTRING { $$ = new NSringConstant(*$1); delete $1; }
;
cst_int : TINTEGER { $$ = new NIntConstant(*$1); delete $1; }
// | TDOUBLE { $$ = new NDouble(atof($1->c_str())); delete $1; }
;
expr : ident TEQUAL expr { $$ = new NAssignment(*$1, *$3); }
| ident TLPAREN call_args TRPAREN { $$ = new NMethodCall(*$1, *$3); delete $3; }
| ident { $$ = $1; }
| cst_int
| cst_string
| binop
| TLPAREN expr TRPAREN { $$ = $2; }
| TTRUE { $$ = new NBool(true); }
| TFALSE { $$ = new NBool(false); }
;
call_args : { $$ = new ExpressionList(); }
| expr { $$ = new ExpressionList(); $$->push_back($1); }
| call_args TCOMMA expr { $1->push_back($3); }
;
binop : expr TCEQ expr { $$ = new NBinaryOperator(*$1, $2, *$3); }
| expr TCNE expr { $$ = new NBinaryOperator(*$1, $2, *$3); }
| expr TCLT expr { $$ = new NBinaryOperator(*$1, $2, *$3); }
| expr TCLE expr { $$ = new NBinaryOperator(*$1, $2, *$3); }
| expr TCGT expr { $$ = new NBinaryOperator(*$1, $2, *$3); }
| expr TCGE expr { $$ = new NBinaryOperator(*$1, $2, *$3); }
| expr TPLUS expr { $$ = new NBinaryOperator(*$1, $2, *$3); }
| expr TMINUS expr { $$ = new NBinaryOperator(*$1, $2, *$3); }
| expr TMUL expr { $$ = new NBinaryOperator(*$1, $2, *$3); }
| expr TDIV expr { $$ = new NBinaryOperator(*$1, $2, *$3); }
| expr TMOD expr { $$ = new NBinaryOperator(*$1, $2, *$3); }
| expr TPOW expr { $$ = new NBinaryOperator(*$1, $2, *$3); }
;
%%