-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathparser.ypp
298 lines (246 loc) · 9.45 KB
/
parser.ypp
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
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
%{
#include <bits/stdc++.h>
#include "PostfixVisitor.h"
extern FILE *yyin;
extern char* yytext;
extern "C" int yylex();
extern int yyparse();
extern FILE *yyin;
extern int line_num;
extern int errors;
void yyerror(const char *s);
int errors=0;
class ProgramASTnode* start = NULL;
%}
%union{
class ProgramASTnode* astnode;
class FieldDec* field;
class FieldDecList* fields;
class Variable* var_decl;
class Variables* var_decls;
class Lit* literal_type;
class Expr* expr_type;
class integerLit* intliteral;
class charLit* charliteral;
class boolLit* boolliteral;
class stringLit* stringliteral;
char* value;
class Block* block_type;
class meth_args* meth_args_type;
class meth_dec* meth_dec_type;
class meth_decs* meth_decs_type;
class var_dec* var_dec_type;
class var_decs* var_decs_type;
class string_list* string_list_type;
class Parameters* parameters_type;
class meth_call* meth_call_type;
class Statements* statements_type;
class Statement* statement_type;
class calloutArgs* callout_args_type;
class calloutArg* callout_arg_type;
class breakState* break_type;
class continueState* continue_type;
class ifElseState* if_block_type;
class forState* for_block_type;
class returnState* return_type;
class Location* location_type;
class Assign* assign_type;
class UnExpr* unaryexp_type;
}
%token END 0
%token EOL
%token CLASS
%token PROGRAM
%token COMMENT
%token <value> VOID
%token L_FLO
%token R_FLO
%token L_SQ
%token R_SQ
%token L_P
%token R_P
%token <value> EQ
%token <value> PE
%token <value> ME
%token COMMA
%token SEMI
%token <value> IDEN
%token <value> BOOLEAN
%token <value> INT
%token <intliteral> INTEGER_LIT
%token <intliteral> HEX_LIT
%token <value> ADD
%token <value> SUB
%token <value> MUL
%token <value> DIV
%token <value> MOD
%token <value> LTHAN
%token <value> GT
%token <value> NOT
%token <charliteral> CHAR_LIT
%token <boolliteral> TRUE
%token <boolliteral> FALSE
%token <value> NE
%token <value> DO
%token <value> GE
%token <value> DA
%token <value> LEQ
%token <value> DE
%token CALLOUT
%token <stringliteral> STRING_LIT
%token RETURN
%token <value> BREAK
%token CONTINUE
%token IF
%token ELSE
%token FOR
%left ADD SUB
%left MUL DIV MOD
%left LEQ GE LTHAN GT DE NE DA DO
%right NOT
%type <astnode> line
%type <fields> field_decl_list
%type <field> field_decl
%type <var_decls> decl_list
%type <var_decl> decl
%type <intliteral> intlit;
%type <meth_decs_type> method_decl_list;
%type <meth_dec_type> method_decl;
%type <meth_args_type> method_args_block;
%type <meth_args_type> type_id_list;
%type <block_type> block;
%type <value> type;
%type <var_decs_type> var_dec_list;
%type <var_dec_type> var_dec;
%type <string_list_type> id_list;
%type <statements_type> statement_list;
%type <statement_type> statement;
%type <meth_call_type> method_call;
%type <value> method_name;
%type <parameters_type> expr_list;
%type <expr_type> expr;
%type <literal_type> literal;
%type <boolliteral> bool_lit;
%type <callout_arg_type> callout_arg
%type <callout_args_type> callout_args
%type <if_block_type> if_block
%type <for_block_type> for_block
%type <location_type> location
%type <value> assign_op
%type <unaryexp_type> unaryexp
%%
line : CLASS PROGRAM L_FLO field_decl_list R_FLO { $$ = new ProgramASTnode("Program Decl", $4, new meth_decs() ); start = $$;}
| CLASS PROGRAM L_FLO field_decl_list method_decl_list R_FLO { $$ = new ProgramASTnode("Program Decl", $4, $5); start = $$;}
| CLASS PROGRAM L_FLO R_FLO { $$ = new ProgramASTnode("Program"); start = $$;}
| CLASS PROGRAM L_FLO method_decl_list R_FLO { $$ = new ProgramASTnode("Program", new FieldDecList() , $4); start = $$;}
field_decl_list : field_decl { $$ = new FieldDecList(); $$->push_back($1);}
| field_decl_list field_decl {$$->push_back($2);}
field_decl : type decl_list SEMI {$$ = new FieldDec(std::string($1), $2);} | COMMENT {$$ = new FieldDec();}
decl_list : decl {$$ = new Variables(); $$->push_back($1);}
| decl_list COMMA decl {$$->push_back($3);}
decl : IDEN { $$ = new Variable(string($1));}
| IDEN L_SQ intlit R_SQ {$$ = new Variable(string($1),$3->getValue());}
type : INT | BOOLEAN;
intlit : HEX_LIT {$$ = $1;}
| INTEGER_LIT {$$ = $1;}
method_decl_list : method_decl { $$ = new meth_decs(); $$->push_back($1);}
| method_decl_list method_decl {$$->push_back($2);}
method_decl : type IDEN method_args_block block {$$ = new meth_dec(std::string($1), $2,$3, $4);}
| VOID IDEN method_args_block block {$$ = new meth_dec(std::string($1), $2,$3, $4);}
method_args_block : L_P type_id_list R_P {$$ = $2;}
| L_P R_P {$$ = new meth_args();}
type_id_list : type IDEN {$$ = new meth_args();$$->push_back(new meth_arg(string($1), string($2)));}
| type_id_list COMMA type IDEN {$$->push_back(new meth_arg(string($3), string($4)));}
block : L_FLO R_FLO {$$ = new Block(new var_decs(), new Statements());}
| L_FLO var_dec_list R_FLO {$$ = new Block($2, new Statements());}
| L_FLO var_dec_list statement_list R_FLO {$$ = new Block($2,$3);}
| L_FLO statement_list R_FLO {$$ = new Block(new var_decs(),$2);}
statement_list : statement {$$ = new Statements(); $$->push_back($1);}
| statement_list statement {$$->push_back($2);}
statement : method_call SEMI {$$ = $1;}
| BREAK SEMI {$$ = new breakState();}
| CONTINUE SEMI {$$ = new continueState();}
| if_block {$$ = $1;}
| for_block {$$ = $1;}
| RETURN expr SEMI {$$ = new returnState($2);}
| RETURN SEMI {$$ = new returnState();}
| location assign_op expr SEMI {$$ = new Assign($1, $2, $3);}
| block {$$ = $1;}
assign_op : EQ {$$ = $1;}
| PE {$$ = $1;}
| ME {$$ = $1;}
for_block : FOR IDEN EQ expr COMMA expr block {$$ = new forState($2, $4, $6, $7); }
if_block : IF L_P expr R_P block {$$ = new ifElseState($3, $5);}
| IF L_P expr R_P block ELSE block {$$ = new ifElseState($3, $5, $7);}
method_call : method_name L_P R_P {$$ = new meth_call(string($1), new Parameters());}
| method_name L_P expr_list R_P {$$ = new meth_call(string($1), $3);}
| CALLOUT L_P STRING_LIT COMMA callout_args R_P {$$ = new callout_call($3->value,$5);}
| CALLOUT L_P STRING_LIT R_P {$$ = new callout_call($3->value,new calloutArgs());}
callout_args : callout_args COMMA callout_arg {$$->push_back($3);}
| callout_arg {$$ = new calloutArgs(); $$->push_back($1);}
callout_arg : expr {$$ = new calloutArg($1);}
| STRING_LIT {$$ = new calloutArg($1);}
method_name : IDEN {$$ = $1;}
expr_list : expr {$$ = new Parameters(); $$->push_back($1);}
| expr_list COMMA expr {$$->push_back($3);}
expr : L_P expr R_P {$$ = new EncExpr($2); $$->updateEdata($2->getEdata());}
| expr ADD expr {$$ = new BinExpr($1, $3, string($2)); $$->updateEdata($1->getEdata()); $$->updateEdata($3->getEdata());}
| expr SUB expr {$$ = new BinExpr($1, $3, string($2)); $$->updateEdata($1->getEdata()); $$->updateEdata($3->getEdata()); }
| expr MUL expr {$$ = new BinExpr($1, $3, string($2)); $$->updateEdata($1->getEdata()); $$->updateEdata($3->getEdata());}
| expr DIV expr {$$ = new BinExpr($1, $3, string($2)); $$->updateEdata($1->getEdata()); $$->updateEdata($3->getEdata());}
| expr MOD expr {$$ = new BinExpr($1, $3, string($2)); $$->updateEdata($1->getEdata()); $$->updateEdata($3->getEdata());}
| expr LEQ expr {$$ = new BinExpr($1, $3, string($2)); $$->updateEdata($1->getEdata()); $$->updateEdata($3->getEdata());}
| expr GE expr {$$ = new BinExpr($1, $3, string($2)); $$->updateEdata($1->getEdata()); $$->updateEdata($3->getEdata());}
| expr LTHAN expr {$$ = new BinExpr($1, $3, string($2)); $$->updateEdata($1->getEdata()); $$->setEdata(1);}
| expr GT expr {$$ = new BinExpr($1, $3, string($2)); $$->updateEdata($1->getEdata()); $$->setEdata(1);}
| expr NE expr {$$ = new BinExpr($1, $3, string($2)); $$->updateEdata($1->getEdata()); $$->setEdata(1);}
| expr DE expr {$$ = new BinExpr($1, $3, string($2)); $$->updateEdata($1->getEdata()); $$->setEdata(1);}
| expr DA expr {$$ = new BinExpr($1, $3, string($2)); $$->updateEdata($1->getEdata()); $$->setEdata(1);}
| expr DO expr {$$ = new BinExpr($1, $3, string($2)); $$->updateEdata($1->getEdata()); $$->setEdata(1);}
| method_call {$$ = $1; $$->updateEdata(::integer);}
| literal {$$ = $1; $$->updateEdata($1->getLitType()); }
| location {$$ = $1; $$->updateEdata(::integer);}
| unaryexp {$$ = $1; $$->updateEdata(::integer);}
unaryexp : SUB expr {$$ = new UnExpr($1, $2);}
| NOT expr {$$ = new UnExpr($1, $2);}
location : IDEN {$$ = new Location($1);}
| IDEN L_SQ expr R_SQ {$$ = new Location($1, $3);}
literal : INTEGER_LIT {$$ = $1;}
| bool_lit {$$ = $1;}
| CHAR_LIT {$$ = $1;}
bool_lit : TRUE {$$=$1;}
| FALSE {$$=$1;}
var_dec_list : var_dec {$$ = new var_decs(); $$->push_back($1);}
| var_dec_list var_dec {$$->push_back($2);}
var_dec : type id_list SEMI {$$ = new var_dec(string($1), $2);}
id_list : IDEN {$$ = new string_list(); $$->push_back(string($1));}
| id_list COMMA IDEN {$$->push_back(string($3));}
%%
int main(int argc, char **argv)
{
if(argc == 1)
{
fprintf(stderr, "Correct usage: parser filename\n");
exit(1);
}
if(argc > 2)
{
fprintf(stderr, "Passing more arguments than necessary.\n");
fprintf(stderr, "Correct usage: parser filename\n");
}
yyin = fopen(argv[1], "r");
printf("\n");
yyparse();
PostFixVisitor* dfs;
dfs=new PostFixVisitor();
start->accept(*dfs);
start->Codegen();
cout << "Errors during IR Generation: " << errors_IR << endl;
if(!errors_IR)
start->generateCodeDump();
printf("\nParsing Over\n");
}
void yyerror(const char *s)
{
fprintf(stderr, "error: %s\n", s);
}