-
Notifications
You must be signed in to change notification settings - Fork 0
/
pparser.py
371 lines (296 loc) · 7.91 KB
/
pparser.py
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
from ply import yacc
from lexer import Lexer
class Parser:
tokens = Lexer().tokens
def __init__(self):
pass
def p_program_declist(self, p):
"""program : declist MAIN LRB RRB block"""
pass
def p_program_main(self, p):
"""program : MAIN LRB RRB block"""
pass
def p_declist_dec(self, p):
"""declist : dec"""
pass
def p_declist_declist(self, p):
"""declist : declist dec"""
pass
def p_dec_vardec(self, p):
"""dec : vardec"""
pass
def p_dec_funcdec(self, p):
"""dec : funcdec"""
pass
def p_type_integer(self, p):
"""type : INTEGER"""
pass
def p_type_float(self, p):
"""type : FLOAT"""
pass
def p_type_boolean(self, p):
"""type : BOOLEAN"""
pass
def p_iddec_id(self, p):
"""iddec : ID"""
pass
def p_iddec_id_lsb(self, p):
"""iddec : ID LSB exp RSB"""
pass
def p_iddec_assign(self, p):
"""iddec : assign """
pass
def p_idlist_iddec(self, p):
"""idlist : iddec"""
pass
def p_idlist_idlist(self, p):
"""idlist : idlist COMMA iddec"""
pass
def p_vardec(self, p):
"""vardec : idlist COLON type SEMICOLON"""
pass
def p_funcdec_type_block(self, p):
"""funcdec : FUNCTION ID LRB paramdecs RRB COLON type block"""
pass
def p_funcdec_block(self, p):
"""funcdec : FUNCTION ID LRB paramdecs RRB block"""
pass
def p_paramdecs_paramdecslist(self, p):
"""paramdecs : paramdecslist"""
pass
def p_paramdecs_lambda(self, p):
"""paramdecs : """
pass
def p_paramdecslist_paramdec(self, p):
"""paramdecslist : paramdec"""
pass
def p_paramdecslist_paramdecslist(self, p):
"""paramdecslist : paramdecslist COMMA paramdec"""
pass
def p_paramdec_id_colon(self, p):
"""paramdec : ID COLON type"""
pass
def p_paramdec_id_lsb(self, p):
"""paramdec : ID LSB RSB COLON type"""
pass
def p_block_lcb_stmtlist(self, p):
"""block : LCB stmtlist RCB"""
pass
def p_block_lcb_rcb(self, p):
"""block : LCB RCB"""
pass
def p_stmtlist_stmt(self, p):
"""stmtlist : stmt"""
pass
def p_stmtlist_stmtlist(self, p):
"""stmtlist : stmtlist stmt"""
pass
def p_lvalue_id(self, p):
"""lvalue : ID"""
pass
def p_lvalue_id_lsb(self, p):
"""lvalue : ID LSB exp RSB"""
pass
def p_case(self, p):
"""case : WHERE const COLON stmtlist"""
pass
def p_cases_case(self, p):
"""cases : case"""
pass
def p_cases_cases(self, p):
"""cases : cases case"""
pass
def p_stmt_return(self, p):
"""stmt : RETURN exp SEMICOLON"""
pass
def p_stmt_exp(self, p):
"""stmt : exp SEMICOLON"""
pass
def p_stmt_block(self, p):
"""stmt : block"""
pass
def p_stmt_vardec(self, p):
"""stmt : vardec"""
pass
def p_stmt_while(self, p):
"""stmt : WHILE LRB exp RRB stmt"""
pass
def p_stmt_on_cases(self, p):
"""stmt : ON LRB exp RRB LCB cases RCB SEMICOLON"""
pass
def p_stmt_on(self, p):
"""stmt : ON LRB exp RRB LCB RCB SEMICOLON"""
pass
def p_stmt_for_exp(self, p):
"""stmt : FOR LRB exp SEMICOLON exp SEMICOLON exp RRB stmt"""
pass
def p_stmt_for_id(self, p):
"""stmt : FOR LRB ID IN ID RRB stmt"""
pass
def p_stmt_print(self, p):
"""stmt : PRINT LRB ID RRB SEMICOLON"""
pass
def p_stmt_if(self, p):
"""stmt : IF LRB exp RRB stmt elseiflist %prec P3"""
pass
def p_stmt_if_else(self, p):
"""stmt : IF LRB exp RRB stmt elseiflist ELSE stmt"""
pass
def p_elseiflist_elseiflist(self, p):
"""elseiflist : elseiflist ELSEIF LRB exp RRB stmt"""
pass
def p_elseiflist_lambda(self, p):
"""elseiflist : """
pass
# def p_relopexp(self, p):
# """relopexp : exp relop exp
# | relopexp relop exp"""
# pass
def p_exp_assign(self, p):
"""exp : assign"""
pass
def p_exp_exp_operator(self, p):
"""exp : exp SUM exp
| exp SUB exp
| exp MUL exp
| exp DIV exp
| exp MOD exp"""
print(p[2])
pass
def p_exp_exp_relop(self, p):
"""exp : exp GT exp
| exp LT exp
| exp LE exp
| exp GE exp
| exp EQ exp
| exp NE exp"""
pass
def p_exp_const(self, p):
"""exp : const"""
pass
def p_exp_lvalue(self, p):
"""exp : lvalue"""
pass
def p_exp_id_explist(self, p):
"""exp : ID LRB explist RRB"""
pass
def p_exp_lrb_exp(self, p):
"""exp : LRB exp RRB"""
pass
def p_exp_id_lrb(self, p):
"""exp : ID LRB RRB"""
pass
def p_exp_sub(self, p):
"""exp : SUB exp"""
pass
def p_exp_not(self, p):
"""exp : NOT exp"""
pass
def p_assign(self, p):
"""assign : lvalue ASSIGN exp"""
pass
def p_operator_and(self, p):
"""operator : AND"""
pass
def p_operator_or(self, p):
"""operator : OR"""
pass
# def p_operator_sum(self, p):
# """operator : SUM"""
# p[0] = p[1]
# pass
#
# def p_operator_sub(self, p):
# """operator : SUB"""
# p[0] = p[1]
# pass
#
#
# def p_operator_mul(self, p):
# """operator : MUL"""
# p[0] = p[1]
# pass
#
# def p_operator_div(self, p):
# """operator : DIV"""
# p[0] = p[1]
# pass
#
# def p_operator_mod(self, p):
# """operator : MOD"""
# p[0] = p[1]
# pass
def p_const_integernumber(self, p):
"""const : INTEGERNUMBER"""
pass
def p_const_floatnumber(self, p):
"""const : FLOATNUMBER"""
pass
def p_const_true(self, p):
"""const : TRUE"""
pass
def p_const_false(self, p):
"""const : FALSE"""
pass
# def p_relop_gt(self, p):
# """relop : GT"""
# pass
#
# def p_relop_lt(self, p):
# """relop : LT"""
# pass
#
# def p_relop_ne(self, p):
# """relop : NE"""
# pass
#
# def p_relop_eq(self, p):
# """relop : EQ"""
# pass
#
# def p_relop_le(self, p):
# """relop : LE"""
# pass
#
# def p_relop_ge(self, p):
# """relop : GE"""
# pass
def p_explist_exp(self, p):
"""explist : exp"""
pass
def p_explist_explist(self, p):
"""explist : explist COMMA exp"""
pass
precedence = (
('left', "OR"),
('left', "AND"),
('left', "NOT"),
('left', "GT", "LT", "NE", "EQ", "LE", "GE"),
('right', "ASSIGN"),
('left', 'P3'),
('left', "MOD"),
('left', "SUM", "SUB"),
('left', "MUL", "DIV"),
('left', "ELSE", "ELSEIF"),
)
# precedence = (
# ('right', 'ASSIGN'),
# ('left', 'P3'),
# ('left', 'ELSE', 'ELSEIF'),
# # ('left', 'P2'),
# # ('left', 'P1'),
# ('left', 'OR'),
# ('left', 'AND'),
# ('left', 'EQ', 'NE'),
# ('left', 'LT', 'GT', 'GE', 'LE'),
# ('left', 'SUM', 'SUB'),
# ('left', 'MUL', 'DIV', 'MOD'),
# ('left', 'NOT')
# )
def p_error(self, p):
print(p.value)
raise Exception('ParsingError: invalid grammar at ', p)
def build(self, **kwargs):
"""build the parser"""
self.parser = yacc.yacc(module=self, **kwargs)
return self.parser