-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathdecaf_parser.ypp
251 lines (244 loc) · 6.76 KB
/
decaf_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
%{
#include "program.h"
#include <bits/stdc++.h>
extern "C" int yylex();
extern int yyparse();
extern FILE *yyin;
extern int line_num;
extern union Node yylval;
extern int errors;
void yyerror(const char *s);
class Program* start = NULL;
int errors=0;
%}
/* ------------- Tokens ------------- */
%start Program
%token CLASS
%token CALLOUT RETURN
%token BREAK CONTINUE
%token IF ELSE FOR
%token COMMA SC
%token <value> BOOLEAN CHAR STRING TYPE ID VOID
%token <number> INTEGER
%token OB CB OSB CSB OP CP
%token <value> COND_AND COND_OR NOT
%token <value> ADD SUB MUL DIV MOD
%token <value> LT GT LE GE
%token <value> EQUAL NOT_EQUAL
%token <value> EQ ADDEQ SUBEQ
/* ------------- Left Precedence ------------- */
/* %define parse.error verbose */
%left EQUAL NOT_EQUAL
%left COND_AND COND_OR
%left LT GT LE GE
%left ADD SUB
%left MUL DIV MOD
%nonassoc NOT
/* ------------- Non-Terminal Types ------------- */
%type <program> Program
%type <fields> Field_declarations
%type <field> Field_declaration
%type <vars> Variables
%type <var> Variable
%type <methods> Method_declarations
%type <method> Method_declaration
%type <method_args> Method_Args
%type <method_args> Method_Arg
%type <block> Block
%type <var_decls> Var_declarations
%type <var_decl> Var_declaration
%type <stmts> Statements
%type <stmt> Statement
%type <assignment> Assignment
%type <parameters> Parameters
%type <function_call> Function_Call
%type <location> Location
%type <expr> Expression
%type <callout_args> Callout_Args
%type <callout_arg> Callout_Arg
%type <literal> Literal;
%type <mylist> Var_names
/* ------------- Grammer Rules ------------- */
%%
Program:
CLASS ID OB Field_declarations Method_declarations CB {
$$ = new Program(string($2),$4,$5);
start = $$;
}
;
Field_declarations:
{
$$ = new fieldDeclarations();
}
| Field_declarations Field_declaration SC {$$->push_back($2);}
;
Field_declaration:
TYPE Variables {$$ = new fieldDeclaration(string($1),$2);}
;
Variables:
Variable {$$ = new Variables();$$->push_back($1);}
| Variables COMMA Variable { $$->push_back($3); }
;
Variable:
ID { $$ = new Variable(string($1));}
| ID OSB INTEGER CSB { $$ = new Variable(string($1),$3);}
;
Method_declarations:
{
$$ = new methodDeclarations();
}
| Method_declaration Method_declarations {$2->push_back($1);$$ = $2;}
;
Method_declaration:
TYPE ID Method_Args Block {$$ = new methodDeclaration(string($1),$2,$3,$4);}
| VOID ID Method_Args Block {$$ = new methodDeclaration(string($1),$2,$3,$4);}
;
Method_Args:
OP CP {$$ = new methodArguments();}
| OP TYPE ID Method_Arg CP {
methodArgument* arg = new methodArgument(string($2),string($3));
$4->push_back(arg);
$$ = $4;
}
;
Method_Arg:
/* Empty */
{
$$ = new methodArguments();
}
| COMMA TYPE ID Method_Arg {
methodArgument* arg = new methodArgument(string($2),string($3));
$4->push_back(arg);
$$ = $4;
}
;
Block:
OB Var_declarations Statements CB {
$$ = new Block($2,$3);
}
;
Var_declarations:
/* Empty */
{
$$ = new variableDeclarations();
}
| Var_declaration SC Var_declarations {$3->push_back($1);$$ = $3;}
;
Var_declaration:
TYPE ID Var_names {
$3->push_back($2);
$$ = new variableDeclaration(string($1),$3);
}
;
Var_names:
/* Empty */
{
$$ = new stringList();
}
| COMMA ID Var_names {$3->push_back(string($2));$$ = $3;}
;
Statements:
/* Empty */
{
$$ = new Statements();
}
| Statements Statement {$$->push_back($2);}
;
Statement:
Assignment {$$ = $1;}
| Function_Call SC {$$ = $1;}
| IF OP Expression CP Block {$$ = new ifElseStatements($3,$5,NULL);}
| IF OP Expression CP Block ELSE Block {$$ = new ifElseStatements($3,$5,$7);}
| FOR ID EQ Expression COMMA Expression Block {
$$ = new forStatement(string($2),$4,$6,$7);
}
| RETURN SC {$$ = new returnStatement(NULL);}
| RETURN Expression SC {$$ = new returnStatement($2);}
| BREAK SC {$$ = new breakStatement();}
| CONTINUE SC {$$ = new continueStatement();}
| Block {$$ = $1;}
;
Assignment:
Location EQ Expression SC {$$ = new Assignment($1,string($2),$3);}
| Location SUBEQ Expression SC {$$ = new Assignment($1,string($2),$3);}
| Location ADDEQ Expression SC {$$ = new Assignment($1,string($2),$3);}
;
Function_Call:
ID OP Parameters CP {$$ = new methodCall(string($1),$3);}
| CALLOUT OP STRING Callout_Args CP {$$ = new calloutCall(string($3),$4);}
;
Parameters:
Expression {$$ = new Parameters();$$->push_back($1);}
| Parameters COMMA Expression {$$->push_back($3);}
;
Location:
ID {$$ = new Location(string($1));}
| ID OSB Expression CSB {$$ = new Location(string($1),$3);}
;
Expression:
Location {$$ = $1;}
| Function_Call {$$ = $1;}
| Literal {$$ = $1;}
| Expression ADD Expression {$$ = new binaryExpression($1,string($2),$3);}
| Expression SUB Expression {$$ = new binaryExpression($1,string($2),$3);}
| Expression MUL Expression {$$ = new binaryExpression($1,string($2),$3);}
| Expression DIV Expression {$$ = new binaryExpression($1,string($2),$3);}
| Expression MOD Expression {$$ = new binaryExpression($1,string($2),$3);}
| Expression LT Expression {$$ = new binaryExpression($1,string($2),$3);}
| Expression GT Expression {$$ = new binaryExpression($1,string($2),$3);}
| Expression LE Expression {$$ = new binaryExpression($1,string($2),$3);}
| Expression GE Expression {$$ = new binaryExpression($1,string($2),$3);}
| Expression EQUAL Expression {$$ = new binaryExpression($1,string($2),$3);}
| Expression NOT_EQUAL Expression {$$ = new binaryExpression($1,string($2),$3);}
| Expression COND_OR Expression {$$ = new binaryExpression($1,string($2),$3);}
| Expression COND_AND Expression {$$ = new binaryExpression($1,string($2),$3);}
| SUB Expression {$$ = new unaryExpression(string($1),$2);}
| NOT Expression {$$ = new unaryExpression(string($1),$2);}
| OP Expression CP {$$ = new enclosedExpression($2);}
;
Callout_Args:
{$$ = new calloutArguments();}
| Callout_Args COMMA Callout_Arg {$$->push_back($3);}
;
Callout_Arg:
Expression {$$ = new calloutArgument($1);}
| STRING {$$ = new calloutArgument(string($1));}
;
Literal:
INTEGER {$$ = new integerLiteral($1);}
| CHAR {$$ = new charLiteral(string($1));}
| BOOLEAN {$$ = new boolLiteral(string($1));}
;
%%
int main(int argc, char **argv) {
if(argc == 1) {
printf("No Input File Given\n");
exit(-1);
}
FILE *input = fopen(argv[1], "r");
if (input == NULL){
printf("Can't open the given file!\n");
exit(-1);
}
yyin = input;
do {
yyparse();
} while (!feof(yyin));
cerr << "Semantical Analysis Success\n";
if(start){
/* Do the code generation part */
start->generateCode();
if(errors == 0){
/* Print the code */
start->generateCodeDump();
}
else{
cerr << errors << " Errors found\n";
}
}
}
void yyerror(const char *s){
errors++;
printf("Error:%s at %d\n",s,line_num);
exit(-1);
}