-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathminim.cup
373 lines (338 loc) · 11.1 KB
/
minim.cup
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
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
/**********************************************************************
Java CUP specification for a parser for minim programs
**********************************************************************/
import java_cup.runtime.*;
import java.util.*;
/* The code below redefines method syntax_error to give better error messages
* than just "Syntax error"
*/
parser code {:
public void syntax_error(Symbol currToken) {
if (currToken.value == null) {
ErrMsg.fatal(0,0, "Syntax error at end of file");
}
else {
ErrMsg.fatal(((TokenVal)currToken.value).lineNum,
((TokenVal)currToken.value).charNum,
"Syntax error");
}
System.exit(-1);
}
:};
/* Terminals (tokens returned by the scanner) */
terminal INT;
terminal BOOL;
terminal VOID;
terminal TokenVal TRUE;
terminal TokenVal FALSE;
terminal STRUCT;
terminal INPUT;
terminal DISP;
terminal IF;
terminal ELSE;
terminal WHILE;
terminal RETURN;
terminal IdTokenVal ID;
terminal IntLitTokenVal INTLITERAL;
terminal StrLitTokenVal STRINGLITERAL;
terminal LCURLY;
terminal RCURLY;
terminal LPAREN;
terminal RPAREN;
terminal SEMICOLON;
terminal COMMA;
terminal DOT;
terminal WRITE;
terminal READ;
terminal PLUSPLUS;
terminal MINUSMINUS;
terminal PLUS;
terminal MINUS;
terminal TIMES;
terminal DIVIDE;
terminal NOT;
terminal AND;
terminal OR;
terminal EQUALS;
terminal NOTEQUALS;
terminal LESS;
terminal GREATER;
terminal LESSEQ;
terminal GREATEREQ;
terminal ASSIGN;
/* Nonterminals */
non terminal ProgramNode program;
non terminal LinkedList declList;
non terminal DeclNode decl;
non terminal LinkedList varDeclList;
non terminal VarDeclNode varDecl;
non terminal FnDeclNode fnDecl;
non terminal StructDeclNode structDecl;
non terminal LinkedList structBody;
non terminal LinkedList formals;
non terminal LinkedList formalsList;
non terminal FormalDeclNode formalDecl;
non terminal FnBodyNode fnBody;
non terminal LinkedList stmtList;
non terminal StmtNode stmt;
non terminal AssignExpNode assignExp;
non terminal ExpNode exp;
non terminal ExpNode term;
non terminal CallExpNode fncall;
non terminal LinkedList actualList;
non terminal TypeNode type;
non terminal ExpNode loc;
non terminal IdNode id;
/* Precedence and associativity declarations */
precedence right ASSIGN;
precedence left OR;
precedence left AND;
precedence nonassoc EQUALS, NOTEQUALS, LESS, GREATER, LESSEQ, GREATEREQ;
precedence left PLUS, MINUS;
precedence left TIMES, DIVIDE;
precedence right NOT;
start with program;
/* Grammar with actions */
program ::= declList: d
{: RESULT = new ProgramNode(new DeclListNode(d));
:}
;
declList ::= declList:dl decl:d
{: dl.addLast(d);
RESULT = dl;
:}
| /* epsilon */
{: RESULT = new LinkedList<DeclNode>();
:}
;
decl ::= varDecl:v
{: RESULT = v;
:}
| fnDecl:f
{: RESULT = f;
:}
| structDecl:s
{: RESULT = s;
:}
;
varDeclList ::= varDeclList:vdl varDecl:vd
{: vdl.addLast(vd);
RESULT = vdl;
:}
| /* epsilon */
{: RESULT = new LinkedList<VarDeclNode>();
:}
;
varDecl ::= type:t id:i SEMICOLON
{: RESULT = new VarDeclNode(t, i, VarDeclNode.NOT_STRUCT);
:}
| STRUCT id:t id:i SEMICOLON
{: RESULT = new VarDeclNode(new StructNode(t), i, 0);
:}
;
fnDecl ::= type:t id:i formals:f fnBody:fb
{: RESULT = new FnDeclNode(t, i, new FormalsListNode(f), fb);
:}
;
structDecl ::= STRUCT id:i LCURLY structBody:sb RCURLY SEMICOLON
{: RESULT = new StructDeclNode(i, new DeclListNode(sb));
:}
;
structBody ::= structBody:sb varDecl:vd
{: sb.addLast(vd);
RESULT = sb;
:}
| varDecl:vd
{: LinkedList<VarDeclNode> list =
new LinkedList<VarDeclNode>();
list.addLast(vd);
RESULT = list;
:}
;
formals ::= LPAREN RPAREN
{: RESULT = new LinkedList<FormalDeclNode>();
:}
| LPAREN formalsList:fl RPAREN
{: RESULT = fl;
:}
;
formalsList ::= formalDecl:fd
{: LinkedList<FormalDeclNode> list =
new LinkedList<FormalDeclNode>();
list.addLast(fd);
RESULT = list;
:}
| formalDecl:fd COMMA formalsList:fl
{: fl.addFirst(fd);
RESULT = fl;
:}
;
formalDecl ::= type:t id:i
{: RESULT = new FormalDeclNode(t, i);
:}
;
fnBody ::= LCURLY varDeclList:vdl stmtList:sl RCURLY
{: RESULT = new FnBodyNode(
new DeclListNode(vdl), new StmtListNode(sl));
:}
;
stmtList ::= stmtList:sl stmt:s
{: sl.addLast(s);
RESULT = sl;
:}
| /* epsilon */
{: RESULT = new LinkedList<StmtNode>();
:}
;
stmt ::= assignExp:ae SEMICOLON
{: RESULT = new AssignStmtNode(ae);
:}
| loc:lc PLUSPLUS SEMICOLON
{: RESULT = new PostIncStmtNode(lc);
:}
| loc:lc MINUSMINUS SEMICOLON
{: RESULT = new PostDecStmtNode(lc);
:}
| INPUT READ loc:lc SEMICOLON
{: RESULT = new ReadStmtNode(lc);
:}
| DISP WRITE exp:e SEMICOLON
{: RESULT = new WriteStmtNode(e);
:}
| IF exp:e LCURLY varDeclList:vdl stmtList:sl RCURLY
{: RESULT = new IfStmtNode(e,
new DeclListNode(vdl), new StmtListNode(sl));
:}
| IF exp:e LCURLY varDeclList:vdlt stmtList:slt RCURLY ELSE LCURLY varDeclList:vdle stmtList:sle RCURLY
{: RESULT = new IfElseStmtNode(e,
new DeclListNode(vdlt), new StmtListNode(slt),
new DeclListNode(vdle), new StmtListNode(sle));
:}
| WHILE exp:e LCURLY varDeclList:vdl stmtList:sl RCURLY
{: RESULT = new WhileStmtNode(e,
new DeclListNode(vdl), new StmtListNode(sl));
:}
| RETURN exp:e SEMICOLON
{: RESULT = new ReturnStmtNode(e);
:}
| RETURN SEMICOLON
{: RESULT = new ReturnStmtNode(null);
:}
| fncall:f SEMICOLON
{: RESULT = new CallStmtNode(f);
:}
;
assignExp ::= loc:lc ASSIGN exp:e
{: RESULT = new AssignExpNode(lc, e);
:}
;
exp ::= assignExp:ae
{: RESULT = ae;
:}
| exp:e1 PLUS exp:e2
{: RESULT = new PlusNode(e1, e2);
:}
| exp:e1 MINUS exp:e2
{: RESULT = new MinusNode(e1, e2);
:}
| exp:e1 TIMES exp:e2
{: RESULT = new TimesNode(e1, e2);
:}
| exp:e1 DIVIDE exp:e2
{: RESULT = new DivideNode(e1, e2);
:}
| NOT exp:e
{: RESULT = new NotNode(e);
:}
| exp:e1 AND exp:e2
{: RESULT = new AndNode(e1, e2);
:}
| exp:e1 OR exp:e2
{: RESULT = new OrNode(e1, e2);
:}
| exp:e1 EQUALS exp:e2
{: RESULT = new EqualsNode(e1, e2);
:}
| exp:e1 NOTEQUALS exp:e2
{: RESULT = new NotEqualsNode(e1, e2);
:}
| exp:e1 LESS exp:e2
{: RESULT = new LessNode(e1, e2);
:}
| exp:e1 GREATER exp:e2
{: RESULT = new GreaterNode(e1, e2);
:}
| exp:e1 LESSEQ exp:e2
{: RESULT = new LessEqNode(e1, e2);
:}
| exp:e1 GREATEREQ exp:e2
{: RESULT = new GreaterEqNode(e1, e2);
:}
| MINUS exp:e
{: RESULT = new UnaryMinusNode(e);
:}
| term:t
{: RESULT = t;
:}
;
term ::= loc:lc
{: RESULT = lc;
:}
| INTLITERAL:i
{: RESULT = new IntLitNode(i.lineNum, i.charNum, i.intVal);
:}
| STRINGLITERAL:s
{: RESULT = new StringLitNode(s.lineNum, s.charNum, s.strVal);
:}
| TRUE:t
{: RESULT = new TrueNode(t.lineNum, t.charNum);
:}
| FALSE:f
{: RESULT = new FalseNode(f.lineNum, f.charNum);
:}
| LPAREN exp:e RPAREN
{: RESULT = e;
:}
| fncall:f
{: RESULT = f;
:}
;
fncall ::= id:i LPAREN RPAREN
{: RESULT = new CallExpNode(i,
new ExpListNode(new LinkedList<ExpNode>()));
:}
| id:i LPAREN actualList:al RPAREN
{: RESULT = new CallExpNode(i, new ExpListNode(al));
:}
;
actualList ::= exp:e
{: LinkedList<ExpNode> list = new LinkedList<ExpNode>();
list.addLast(e);
RESULT = list;
:}
| actualList:al COMMA exp:e
{: al.addLast(e);
RESULT = al;
:}
;
type ::= INT
{: RESULT = new IntNode();
:}
| BOOL
{: RESULT = new BoolNode();
:}
| VOID
{: RESULT = new VoidNode();
:}
;
loc ::= id:i
{: RESULT = i;
:}
| loc:lc DOT id:i
{: RESULT = new DotAccessExpNode(lc, i);
:}
;
id ::= ID:i
{: RESULT = new IdNode(i.lineNum, i.charNum, i.idVal);
:}
;