-
Notifications
You must be signed in to change notification settings - Fork 0
/
yacc_parser.py
169 lines (110 loc) · 3.4 KB
/
yacc_parser.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
import os
import ply.yacc as yacc
from lex_parser import tokens
import AST
def p_programme_statement(p):
''' programme : statement '''
p[0] = AST.ProgramNode(p[1])
def p_programme_recursive(p):
''' programme : statement programme '''
p[0] = AST.ProgramNode([p[1]] + p[2].children)
def p_statement(p):
''' statement : method
| routine
| function
| assignation
| structure'''
p[0] = p[1]
def p_structure_while(p):
''' structure : WHILE expression '{' programme '}' '''
p[0] = AST.WhileNode([p[2], p[4]])
def p_structure_ifelse(p):
''' structure : IF expression '{' programme '}' ELSE '{' programme '}' '''
p[0] = AST.IfElseNode([p[2], p[4], p[8]])
def p_structure_if(p):
''' structure : IF expression '{' programme '}' '''
p[0] = AST.IfNode([p[2], p[4]])
def p_assign(p):
''' assignation : VARIABLE '=' expression '''
p[0] = AST.AssignNode([AST.VariableNode(p[1]), p[3]])
def p_assign_routine(p):
''' assignation : ROUTINE '=' '{' programme '}' '''
p[0] = AST.AssignRoutineNode([AST.VariableNode(p[1]), p[4]])
def p_method(p):
''' method : METHODS '(' ')' '''
p[0] = AST.MethodNode(p[1])
def p_method_arg(p):
''' method : METHODS '(' arguments ')' '''
p[0] = AST.MethodNode(p[1], [p[3]])
def p_function(p):
''' function : FUNCTIONS '(' ')' '''
p[0] = AST.FunctionNode(p[1])
def p_func_arg(p):
''' function : FUNCTIONS '(' arguments ')' '''
p[0] = AST.FunctionNode(p[1], [p[3]])
def p_arguments(p):
''' arguments : expression '''
p[0] = AST.ArgumentNode(p[1])
def p_arguments_recursive(p):
''' arguments : expression ',' arguments '''
p[0] = AST.ArgumentNode([p[1]] + p[3].children)
def p_expression(p):
'''expression : NUMBER '''
p[0] = AST.TokenNode(p[1])
def p_expression_string(p):
'''expression : STRING '''
p[0] = AST.TokenNode(p[1])
def p_expression_var(p):
''' expression : VARIABLE '''
p[0] = AST.VariableNode(p[1])
def p_routine(p):
''' routine : ROUTINE '(' ')' '''
p[0] = AST.CallRoutineNode(p[1])
def p_expression_func(p):
'''expression : function'''
p[0] = p[1]
def p_expression_paren(p):
'''expression : '(' expression ')' '''
p[0] = p[2]
def p_expression_op(p):
'''expression : expression ADD_OP expression
| expression MUL_OP expression
| expression POW_OP expression
| expression MOD_OP expression
| expression CONDITION_OP expression'''
p[0] = AST.OpNode(p[2], [p[1], p[3]])
def p_minus(p):
'''expression : ADD_OP expression %prec UMINUS'''
p[0] = AST.OpNode(p[1], [p[2]])
# p[0] = AST.TokenNode(p[2])
def p_error(p):
if p:
print("Syntax error in line %d" % p.lineno)
yacc.errok()
else:
print("Sytax error: unexpected end of file!")
precedence = (
('left', 'CONDITION_OP'),
('left', 'ADD_OP'),
('left', 'MUL_OP'),
('left', 'POW_OP'),
('left', 'MOD_OP'),
('right', 'UMINUS'),
)
def parse(program):
return yacc.parse(program)
if not os.path.exists("generated"):
os.mkdir("generated")
yacc.yacc(outputdir='generated')
if __name__ == "__main__":
import sys
try:
filename = sys.argv[1]
except:
filename = "test.txt"
prog = open(filename).read()
result = yacc.parse(prog)
if result:
print(result)
else:
print("Parsing returned no result!")