-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathparser_.py
More file actions
169 lines (148 loc) · 7.06 KB
/
Copy pathparser_.py
File metadata and controls
169 lines (148 loc) · 7.06 KB
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
class Parser:
def __init__(self):
self.lexing_result = [] # 先前词法分析得到的结果
self.parsing_result = [] # 语法分析结果
self.token = [] # 当前词 [词性, 内容]
self.current = -1 # 当前词位置
self.error = 0 # 语法分析异常数量
self.number_stack = [] # 数字栈
self.operator_stack = [] # 符号栈
self.operator_priority = {'(': 0, ')': 0, '+': 1, '-': 1, '*': 2, '/': 2} # 算符优先级
self.semantic_result = [] # 语义分析结果
self.semantic_error = -1 # 语义分析报错
self.semantic_error_num = 0 # 语义分析报错数量
self.intermediate_code_result = [] # 中间代码生成结果
self.intermediate_code_result_store = [] # 中间代码生成结果存储
self.temp_num = 1 # 临时变量的数量
# 语法分析
def parsing(self, lexing_result: list) -> list:
self.lexing_result = lexing_result
self.get_next_token()
rollback_stack = [] # 回溯栈
while self.current < len(self.lexing_result): # 每一句表达式结束 就开始判断下一句是否为表达式
rollback_stack.append([self.current, self.token])
success = self.parse_condition() # 条件表达式?
# if not success:
# self.current, self.token = rollback_stack.pop(-1)
# rollback_stack.append([self.current, self.token])
# success = self.parse_expression() # 表达式?
rollback_stack.pop(-1)
if self.current > len(self.lexing_result):
self.parsing_result.append(['fail', 'EOF', 'EOF'])
self.operator_stack = []
self.number_stack = []
self.temp_num = 1
self.intermediate_code_result_store = []
self.intermediate_code_result.append('语法分析有误,无法生成中间代码')
self.error += 1
else:
if success:
self.parsing_result.append(['success', self.current - 1, self.lexing_result[self.current - 1]])
while len(self.operator_stack):
self.eval()
self.temp_num = 1
self.number_stack = []
for item in self.intermediate_code_result_store:
self.intermediate_code_result.append(item)
self.intermediate_code_result_store = []
else:
self.parsing_result.append(['fail', self.current - 1, self.lexing_result[self.current - 1]])
self.operator_stack = []
self.number_stack = []
self.temp_num = 1
self.intermediate_code_result_store = []
self.intermediate_code_result.append('语法分析有误,无法生成中间代码')
self.error += 1
return self.parsing_result
# 从词法分析结果中取词
def get_next_token(self) -> None:
self.current += 1
self.token = self.lexing_result[self.current] if self.current < len(self.lexing_result) else ['EOF', 'EOF']
# 获取新token 最后一词则设为EOF
# 条件分析
def parse_condition(self) -> bool: # <条件> ::=<表达式>[=|#|<|>|<=|>=]<表达式>
if self.token[0] == 'oddsym':
self.get_next_token()
success = self.parse_expression()
else:
success = self.parse_expression() # <表达式>
while success and self.is_compare_operator(): # <比较运算符>
self.get_next_token()
success = self.parse_expression()
return success
# 表达式 分析
def parse_expression(self) -> bool: # <表达式> ::= [+|-]<项>{<加法运算符> <项>}
if self.is_add_operator(): # [+|-]
print(self.operator_stack)
while len(self.operator_stack) and (self.operator_priority[self.operator_stack[-1]] >= self.operator_priority[self.token[1]]):
self.eval()
self.operator_stack.append(self.token[1])
self.get_next_token()
success = self.parse_term() # <项>
while success and self.is_add_operator(): # {<加法运算符> ...}
while len(self.operator_stack) and (
self.operator_priority[self.operator_stack[-1]] >= self.operator_priority[self.token[1]]):
self.eval()
self.operator_stack.append(self.token[1])
self.get_next_token()
success = self.parse_term() # <项>
return success
# 项 分析
def parse_term(self) -> bool: # <项> ::= <因子>{<乘法运算符> <因子>}
success = self.parse_factor() # <因子>
while success and self.is_multiply_operator(): # {<乘法运算符> ...}
while len(self.operator_stack) and self.operator_priority[self.operator_stack[-1]] >= self.operator_priority[self.token[1]]:
self.eval()
self.operator_stack.append(self.token[1])
self.get_next_token()
success = self.parse_factor() # <因子>
return success
# 因子 分析
def parse_factor(self) -> bool: # <因子> ::= <标识符>|<无符号整数>| '('<条件表达式>')'
if self.is_ident() or self.is_number(): # <标识符>|<无符号整数>
self.number_stack.append(self.token[1])
self.get_next_token()
return True
elif self.token[0] == 'lparen': # | '('<条件表达式>')'
self.operator_stack.append(self.token[1])
self.get_next_token()
if not self.parse_condition():
return False
if self.token[0] == 'rparen':
while self.operator_stack[-1] != '(':
self.eval()
self.operator_stack.pop()
self.get_next_token()
return True
self.get_next_token()
return False
# 加法运算符
def is_add_operator(self) -> bool:
pos, content = self.token
return pos == 'plus' or pos == 'minus'
# 乘法运算符
def is_multiply_operator(self) -> bool:
pos, content = self.token
return pos == 'times' or pos == 'slash'
# 标识符
def is_ident(self) -> bool:
pos, content = self.token
return pos == 'ident'
# 无符号整数(非标识符整数)
def is_number(self) -> bool:
pos, content = self.token
return pos == 'number'
# 比较运算符
def is_compare_operator(self) -> bool:
pos, content = self.token
return pos == 'eql' or pos == 'neq' or pos == 'lss' or pos == 'leq' or pos == 'gtr' or pos == 'geq'
# 算术计算
def eval(self):
b = self.number_stack.pop()
a = self.number_stack.pop()
p = self.operator_stack.pop()
t = 'T'+str(self.temp_num)
s = (p, a, b, t)
self.intermediate_code_result_store.append(s)
self.number_stack.append(t)
self.temp_num += 1