├── .idea
├── .gitignore
├── compiler.iml
├── inspectionProfiles
│ └── profiles_settings.xml
├── misc.xml
└── modules.xml
├── __pycache__
├── cifafenxi.cpython-39.pyc
├── jieshichengxu.cpython-39.pyc
├── yufafenxi.cpython-39.pyc
├── yuyifenxi.cpython-39.pyc
└── zhongjiandaima.cpython-39.pyc
├── cifafenxi.py
├── code1.txt
├── code2.txt
├── code3.txt
├── code4.txt
├── code5.txt
├── code6.txt
├── code7.txt
├── compiler.py
├── jieshichengxu.py
├── ll1_table.txt
├── quadruples.txt
├── readme.txt
├── yufafenxi.py
├── yuyifenxi.py
└── zhongjiandaima.py
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # 默认忽略的文件
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/.idea/compiler.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/__pycache__/cifafenxi.cpython-39.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/markwu7777/markwu_compiler/e9fcaf2246e4cf2b9c9ecaa3818d7ee9c44114a4/__pycache__/cifafenxi.cpython-39.pyc
--------------------------------------------------------------------------------
/__pycache__/jieshichengxu.cpython-39.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/markwu7777/markwu_compiler/e9fcaf2246e4cf2b9c9ecaa3818d7ee9c44114a4/__pycache__/jieshichengxu.cpython-39.pyc
--------------------------------------------------------------------------------
/__pycache__/yufafenxi.cpython-39.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/markwu7777/markwu_compiler/e9fcaf2246e4cf2b9c9ecaa3818d7ee9c44114a4/__pycache__/yufafenxi.cpython-39.pyc
--------------------------------------------------------------------------------
/__pycache__/yuyifenxi.cpython-39.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/markwu7777/markwu_compiler/e9fcaf2246e4cf2b9c9ecaa3818d7ee9c44114a4/__pycache__/yuyifenxi.cpython-39.pyc
--------------------------------------------------------------------------------
/__pycache__/zhongjiandaima.cpython-39.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/markwu7777/markwu_compiler/e9fcaf2246e4cf2b9c9ecaa3818d7ee9c44114a4/__pycache__/zhongjiandaima.cpython-39.pyc
--------------------------------------------------------------------------------
/cifafenxi.py:
--------------------------------------------------------------------------------
1 | class Lexer:
2 | def __init__(self):
3 | # 定义保留字和运算符
4 | self.reserve_words = ["if", "else", "while", "return", "int"]
5 | self.operators = ["+", "-", "*", "/", "=", "==", "!=", "<", "<=", ">", ">=", "&&", "||", "!","++","--"]
6 | self.delimiters = [";", ",", "(", ")", "{", "}"]
7 | self.token = ""
8 | self.tokens = []
9 |
10 | def is_reserve(self, word):
11 | return word in self.reserve_words
12 |
13 | def is_operator(self, char):
14 | return char in self.operators
15 |
16 | def is_delimiter(self, char):
17 | return char in self.delimiters
18 |
19 | def tokenize(self, code):
20 | i = 0
21 | while i < len(code):
22 | if code[i].isspace():
23 | i += 1
24 | continue
25 | elif code[i].isalpha(): # 开始是字母,可能是保留字或者变量名
26 | start = i
27 | while i < len(code) and (code[i].isalpha() or code[i].isdigit()):
28 | i += 1
29 | word = code[start:i]
30 | if self.is_reserve(word):
31 | self.tokens.append(("RESERVE_WORD",word))
32 | else:
33 | self.tokens.append(("IDENTIFIER",word))
34 | elif code[i].isdigit(): # 开始是数字,可能是常数
35 | start = i
36 | while i < len(code) and code[i].isdigit():
37 | i += 1
38 | self.tokens.append(("CONSTANT",code[start:i]))
39 | elif self.is_operator(code[i]):
40 | op=code[i]
41 | if i+1 FD P | ε
58 | FD -> T ID '(' PL ')' CS
59 | T -> 'int' | 'float' | 'char' | 'void'
60 | PL -> PD PL' | ε
61 | PL' -> ',' PD PL' | ε
62 | PD -> T ID
63 | CS -> '{' DL SL '}'
64 | DL -> D DL | ε
65 | D -> T ID ';'
66 | SL -> S SL | ε
67 | S -> ES | CS | ';' | CS
68 | ES -> E ';'
69 | CS -> 'if' '(' E ')' S | 'while' '(' E ')' S
70 | E -> AE
71 | AE -> ID '=' AE | LE
72 | LE -> LE '||' RE | RE
73 | RE -> RE '&&' AE | AE
74 | AE -> AE '+' ME | AE '-' ME | ME
75 | ME -> ME '*' F | ME '/' F | F
76 | F -> '(' E ')' | ID | CONST
77 | """
78 | if __name__ == '__main__' :
79 | code = "int main() {int number;int a;number = 10;if (number > 0) {a = number;}else {a = 2;}}"
80 | lexer = Lexer()
81 | tokens = lexer.tokenize(code)
82 | for token in tokens:
83 | print(token)
84 |
--------------------------------------------------------------------------------
/code1.txt:
--------------------------------------------------------------------------------
1 | int main()
2 | {int a ;
3 | a=5;
4 | if (a > 3)
5 | {a = a + 2;}
6 | }
--------------------------------------------------------------------------------
/code2.txt:
--------------------------------------------------------------------------------
1 | int main(){
2 | int number;
3 | number = 10;
4 | int a;
5 | if (number > 0) {
6 | a = number;
7 | }
8 | else {
9 | a = 2;
10 | }
11 | }
--------------------------------------------------------------------------------
/code3.txt:
--------------------------------------------------------------------------------
1 | int main(){
2 | int a;
3 | int b;
4 | int c;
5 | a = 5;
6 | b = 5;
7 | while (a>0)
8 | {
9 | c = a + b;
10 | a--;
11 | }
12 | if(c>10)
13 | {c = 10;
14 | }
15 | }
--------------------------------------------------------------------------------
/code4.txt:
--------------------------------------------------------------------------------
1 | int main(){
2 | int a;
3 | int b;
4 | int c;
5 | a = 5;
6 | b = 5;
7 | while (a>0)
8 | {
9 | c = a + b;
10 | a--;
11 | }
12 | if(c>10)
13 | {c = 10;
14 | }
15 | }
--------------------------------------------------------------------------------
/code5.txt:
--------------------------------------------------------------------------------
1 | int main(){
2 | int b;
3 | int c;
4 | a = 5;
5 | b = 5;
6 | while (a>0)
7 | {
8 | c = a + b;
9 | a--;
10 | }
11 | if(c>10)
12 | {c = 10;
13 | }
14 | }
--------------------------------------------------------------------------------
/code6.txt:
--------------------------------------------------------------------------------
1 | int main(){
2 | int a;
3 | int b;
4 | int c;
5 | a = 5;
6 | b = 5;
7 | while (a>0)
8 | {
9 | c = a + b;
10 | a--;
11 | }
12 | if(c>10)
13 | {c = 10;
14 | }
15 |
--------------------------------------------------------------------------------
/code7.txt:
--------------------------------------------------------------------------------
1 | int main(){
2 | int a;
3 | int b;
4 | int c;
5 | a = 5;
6 | b = 5;
7 | while (a>0)
8 | {
9 | c = a + b;
10 | a--;
11 | }
12 | if(c>10)
13 | {c = 10;
14 | if(c>5)
15 | {
16 | c = 6;
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/compiler.py:
--------------------------------------------------------------------------------
1 | # 主编译器脚本 compiler.py
2 |
3 | from cifafenxi import Lexer
4 | from yufafenxi import Parser
5 | from jieshichengxu import Interpreter
6 |
7 |
8 | class Compiler:
9 | def __init__(self,code):
10 | self.code=code
11 | self.lexer=Lexer()#词法分析
12 | self.tokens = self.lexer.tokenize(code)#生成令牌
13 | self.parser=Parser(self.tokens)
14 | self.interpreter=Interpreter(self.parser.quadruples)
15 |
16 | def compile(self):
17 | # 语法分析、语义分析、四元式生成
18 | print(self.tokens)
19 | self.parser.program()
20 | print(self.parser.symbol_table.table)
21 | print(self.parser.quadruples)
22 | # 解释执行
23 | result = self.interpreter.execute()
24 |
25 | return result
26 |
27 | #读取存放代码的txt文件
28 | with open("code1.txt","r",encoding="utf-8") as f :
29 | code = f.read()
30 | print(code)
31 |
32 | # 创建编译器实例
33 | compiler=Compiler(code)
34 |
35 | # 执行编译过程
36 | result=compiler.compile()
37 | #展示运行结果
38 | for var,value in result.items():
39 | print(f"{var} = {value}")
40 |
--------------------------------------------------------------------------------
/jieshichengxu.py:
--------------------------------------------------------------------------------
1 | class Interpreter:
2 | def __init__(self, quadruples):
3 | self.quadruples = quadruples
4 | self.variables = {}
5 | self.labels = {}
6 |
7 | def execute(self):
8 | # 首先,找出所有标签的位置
9 | for i, quad in enumerate(self.quadruples):
10 | if quad[0] and quad[0].startswith('label'):
11 | self.labels[quad[0]] = i
12 |
13 | # 然后,从第一个四元式开始执行
14 | i = 0
15 | while i1 else None
19 | arg1=quad[2] if len(quad)>2 else None
20 | arg2=quad[3] if len(quad)>3 else None
21 | result=quad[4] if len(quad)>4 else None
22 |
23 | if op == '=': # 赋值操作
24 | self.variables[result] = self.variables.get(arg1, arg1)
25 | elif op in ['+', '-', '*', '/']: # 算术操作
26 | self.variables[result] = eval(f"{self.variables.get(arg1, arg1)} {op} {self.variables.get(arg2, arg2)}")
27 | elif op in ['>', '<', '==', '<=', '>=', '!=']: # 关系操作
28 | self.variables[result] = eval(f"{self.variables.get(arg1, arg1)} {op} {self.variables.get(arg2, arg2)}")
29 | elif op == 'jfalse': # 条件跳转
30 | if not self.variables.get(arg1, arg1):
31 | i = self.labels[result]
32 | continue
33 | elif op == 'jump': # 无条件跳转
34 | i = self.labels[result]
35 | continue
36 | elif op in ['++', '--']: # 自增和自减操作
37 | self.variables[result] = eval(f"{self.variables.get(arg1, arg1)} {op[0]} 1")
38 |
39 | i += 1
40 |
41 | return self.variables # 返回所有变量的最终值
42 | if __name__ == '__main__':
43 | quadruples = [('label1', '=', '10', None, 'number'), ('label2', '>', 'number', '0', 't0'), ('jfalse', 't0', None, 'label4'), ('label3', '=', 'number', None, 'a'), ('jump', None, None, 'label6'), ('label5', '=', '2', None, 'a')]
44 | # 创建解释器实例并执行四元式序列
45 | interpreter = Interpreter(quadruples)
46 | variables = interpreter.execute()
47 |
48 | # 打印所有变量的最终值
49 | for var, value in variables.items():
50 | print(f"{var} = {value}")
51 |
--------------------------------------------------------------------------------
/ll1_table.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/markwu7777/markwu_compiler/e9fcaf2246e4cf2b9c9ecaa3818d7ee9c44114a4/ll1_table.txt
--------------------------------------------------------------------------------
/quadruples.txt:
--------------------------------------------------------------------------------
1 | <__main__.Quadruple object at 0x0000023D8C325E20>
2 |
--------------------------------------------------------------------------------
/readme.txt:
--------------------------------------------------------------------------------
1 | 编译原理课程设计
2 | 由于本人期末考试在编译课设期间穿插,所以赶时间弄的,不过这个麻雀虽小五脏俱全,验收结果不错;整体为token匹配的递归下降实现,语义分析只做了符号表相关
3 |
4 |
5 | 后续可提高部分:没有做界面和更进一步的语义分析,词法分析那块注释和函数的部分也没落实好,语法分析已经按函数的部分弄了(因为main函数),上述可提高的这些的调试可以跟上来。保留字那块可以多添加一些,后续可以操作print以及数组部分的。当然还有其他部分(报错的优化),加油!
6 |
--------------------------------------------------------------------------------
/yufafenxi.py:
--------------------------------------------------------------------------------
1 | #穿插的语义分析,当下只有符号表
2 | class SymbolTable:
3 | def __init__(self):
4 | self.table = {}
5 |
6 | def add(self, identifier, info):
7 | self.table[identifier] = info
8 |
9 | def lookup(self, identifier):
10 | return self.table.get(identifier, None)
11 |
12 | #语法分析,以令牌匹配形式结合递归下降实现
13 | class Parser:
14 | def __init__(self, tokens):
15 | # 初始化解析器,tokens是词法分析器输出的令牌列表
16 | self.tokens = tokens + [('END', -1)] # 在令牌列表末尾添加结束标记
17 | self.index = 0
18 | self.lookahead = self.tokens[self.index]
19 | self.bracket_stack = [] # 用于跟踪括号匹配的栈
20 | self.symbol_table=SymbolTable() # 创建符号表实例
21 | self.quadruples=[] # 创建四元式列表
22 | self.label_counter = 0
23 |
24 | def match(self, expected_type):
25 | # 如果当前令牌是结束标记,则检查括号是否匹配
26 | if self.lookahead[0] == 'END':
27 | if self.bracket_stack:
28 | raise SyntaxError("括号没有正确匹配")
29 | return
30 | # 匹配当前令牌类型,如果匹配则消耗令牌,否则抛出语法错误
31 | if self.lookahead[0] == expected_type:
32 | # 如果是左括号或左大括号,推入栈中
33 | if self.lookahead[1] in ['(', '{']:
34 | self.bracket_stack.append(self.lookahead[1])
35 | # 如果是右括号或右大括号,从栈中弹出并检查匹配
36 | elif self.lookahead[1] in [')', '}']:
37 | if not self.bracket_stack or \
38 | (self.lookahead[1] == ')' and self.bracket_stack[-1] != '(') or \
39 | (self.lookahead[1] == '}' and self.bracket_stack[-1] != '{'):
40 | raise SyntaxError("括号没有正确匹配")
41 | self.bracket_stack.pop()
42 | self.index += 1
43 | if self.index < len(self.tokens):
44 | self.lookahead = self.tokens[self.index]
45 | else:
46 | self.lookahead = None
47 | else:
48 | raise SyntaxError(f"预期的 {expected_type},但是得到了 {self.lookahead[0]}")
49 |
50 | def new_label(self):
51 | self.label_counter+=1
52 | return f"label{self.label_counter}"
53 |
54 | def get_label(self):
55 | return f"label{self.label_counter}"
56 |
57 | def program(self):
58 | # 解析程序,即一系列函数定义
59 | while (self.lookahead and self.lookahead[0] != 'END'): # 检查是否到达结束标记
60 | self.function_definition()
61 | # 到达结束标记,解析结束
62 |
63 | def function_definition(self):
64 | # 解析函数定义
65 | self.type()
66 | self.match("IDENTIFIER")
67 | self.match("DELIMITER")
68 | self.parameter_list()
69 | self.match("DELIMITER")
70 | self.compound_statement()
71 |
72 | def type(self):
73 | # 检查当前令牌是否为数据类型关键字,并消耗它
74 | if self.lookahead[0] == "RESERVE_WORD" and self.lookahead[1] in ["int", "float", "char", "void"]:
75 | type_name = self.lookahead[1]
76 | self.match("RESERVE_WORD")
77 | return type_name
78 | else:
79 | raise SyntaxError("预期的数据类型关键字")
80 |
81 | def parameter_list(self):
82 | # 解析参数列表
83 | if self.lookahead and self.lookahead[0] == "RESERVE_WORD":
84 | self.parameter_declaration()
85 | while self.lookahead and self.lookahead[0] == "DELIMITER" and self.lookahead[1] == ",":
86 | self.match("DELIMITER")
87 | self.parameter_declaration()
88 |
89 | def parameter_declaration(self):
90 | # 解析单个参数声明
91 | self.type()
92 | self.match("IDENTIFIER")
93 |
94 | def compound_statement(self):
95 | # 解析复合语句,即由大括号包围的语句块
96 | self.match("DELIMITER")
97 | # 确保声明列表和语句列表方法存在
98 | self.declaration_list()
99 | self.statement_list()
100 | self.match("DELIMITER")
101 |
102 | def declaration_list(self):
103 | # 解析声明列表
104 | while self.lookahead[0] == "RESERVE_WORD":
105 | self.declaration()
106 |
107 | def declaration(self):
108 | # 解析单个声明
109 | var_type=self.type() # 获取变量的类型
110 | identifier=self.lookahead[1]
111 | self.match("IDENTIFIER")
112 | self.match("DELIMITER")
113 | # 将变量添加到符号表,使用解析到的类型
114 | self.symbol_table.add(identifier,{'type':var_type,'scope':'local'})
115 |
116 | def statement_list(self):
117 | # 解析语句列表
118 | while self.lookahead and self.lookahead[0] in ["IDENTIFIER","RESERVE_WORD","DELIMITER"]:
119 | # 如果遇到右大括号,立即返回
120 | if self.lookahead[0]=="DELIMITER" and self.lookahead[1]=="}":
121 | return
122 | self.statement() # 解析单个语句
123 |
124 | def statement(self):
125 | # 解析单个语句
126 | if self.lookahead[0] == "IDENTIFIER":
127 | self.expression_statement()
128 | elif self.lookahead[1] in ["if", "while"]:
129 | self.control_statement()
130 | elif self.lookahead[0] == "DELIMITER" and self.lookahead[1] == "{":
131 | self.compound_statement()
132 | else:
133 | self.match("DELIMITER")
134 |
135 | def expression_statement(self):
136 | # 解析表达式语句
137 | self.expression()
138 | # 确保每个表达式语句后面都有一个分号
139 | print(self.lookahead[0])
140 | if self.lookahead[0]!="DELIMITER" or self.lookahead[1]!=';':
141 | raise SyntaxError("缺少语句结束符号 ';' ")
142 | self.match("DELIMITER") # 匹配分号
143 |
144 | def control_statement(self):
145 | # 解析控制语句
146 | if self.lookahead[1]=="if":
147 | self.if_statement()
148 | elif self.lookahead[1]=="while":
149 | self.while_statement()
150 | else:
151 | raise SyntaxError("未知的控制语句")
152 | def expression(self):
153 | # 解析表达式
154 | return self.assignment_expression()
155 |
156 | def assignment_expression(self):
157 | # 解析赋值表达式
158 | if self.lookahead[0]=="IDENTIFIER":
159 | identifier=self.lookahead[1]
160 | if not self.symbol_table.lookup(identifier):
161 | raise SyntaxError(f"未声明的变量 '{identifier}' 使用")
162 | self.match("IDENTIFIER")
163 | if self.lookahead[1] in ['++','--']:
164 | operator=self.lookahead[1]
165 | self.match("OPERATOR")
166 | # 创建并返回四元式
167 | quad=(self.new_label(),operator,identifier,None,identifier)
168 | self.quadruples.append(quad) # 将四元式添加到列表中
169 | return quad
170 | else:
171 | self.match("OPERATOR") # 匹配赋值操作符
172 | # 确保赋值操作符后面有一个有效的表达式
173 | if self.lookahead[0] not in ["IDENTIFIER","CONSTANT"]:
174 | raise SyntaxError("赋值操作符后缺少表达式")
175 | # 处理右侧的表达式
176 | right_hand_side=self.additive_expression()
177 | # 创建并返回赋值四元式
178 | assign_quad=(self.new_label(),'=',right_hand_side,None,identifier)
179 | self.quadruples.append(assign_quad) # 将四元式添加到列表中
180 | return assign_quad
181 | else:
182 | self.logical_expression() # 处理逻辑表达式
183 |
184 | def logical_expression(self):
185 | # 首先检查是否有逻辑非运算符 '!'
186 | left=self.relational_expression() # 解析第一个关系表达式
187 | while self.lookahead[0]=="OPERATOR" and self.lookahead[1] in ["!","||","&&"]:
188 | operator=self.lookahead[1]
189 | self.match("OPERATOR")
190 | if operator=="!":
191 | # 对于逻辑非运算符,不需要解析右操作数
192 | right=None
193 | else:
194 | right=self.relational_expression() # 解析下一个关系表达式
195 | temp_var=self.new_temp() # 创建新的临时变量
196 | quad=(self.new_label(),operator,left,right,temp_var) # 创建四元式
197 | self.quadruples.append(quad) # 将四元式添加到列表中
198 | left=temp_var # 更新左侧表达式为临时变量
199 | return left # 返回逻辑表达式的结
200 |
201 | def relational_expression(self):
202 | left=self.additive_expression()
203 | while self.lookahead[0]=="OPERATOR" and self.lookahead[1] in ["<",">","==","<=",">=","!="]:
204 | operator=self.lookahead[1]
205 | self.match("OPERATOR")
206 | right=self.additive_expression()
207 | temp_var=self.new_temp()
208 | quad=(self.new_label(),operator,left,right,temp_var)
209 | self.quadruples.append(quad)
210 | left=temp_var
211 | return left
212 |
213 | def additive_expression(self):
214 | # 解析加减表达式并返回四元式
215 | left=self.multiplicative_expression() # 解析第一个乘除表达式
216 | while self.lookahead[0]=="OPERATOR" and self.lookahead[1] in ["+","-","++","--"]:
217 | operator=self.lookahead[1]
218 | self.match("OPERATOR")
219 | if operator in ["++","--"]:
220 | # 对于一元运算符 '++' 和 '--',不需要解析右操作数
221 | right='1'
222 | else:
223 | # 检查下一个令牌是否是一个有效的操作数
224 | if self.lookahead[0] not in ["IDENTIFIER","CONSTANT"]:
225 | raise SyntaxError("加法或减法操作符后缺少操作数")
226 | right=self.multiplicative_expression() # 解析下一个乘除表达式
227 | temp_var=self.new_temp() # 创建新的临时变量
228 | quad=(self.new_label(),operator,left,right,temp_var) # 创建四元式
229 | self.quadruples.append(quad) # 将四元式添加到列表中
230 | left=temp_var # 更新左侧表达式为临时变量
231 | return left # 返回加减表达式的结果
232 |
233 | def multiplicative_expression(self):
234 | # 解析乘除表达式并返回四元式
235 | left=self.factor() # 解析第一个因子
236 | while self.lookahead[0]=="OPERATOR" and self.lookahead[1] in ["*","/"]:
237 | operator=self.lookahead[1]
238 | self.match("OPERATOR")
239 | right=self.factor() # 解析下一个因子
240 | temp_var=self.new_temp() # 创建新的临时变量
241 | quad=(self.new_label(),operator,left,right,temp_var) # 创建四元式
242 | self.quadruples.append(quad) # 将四元式添加到列表中
243 | left=temp_var # 更新左侧因子为临时变量
244 | return left # 返回乘除表达式的结果
245 |
246 | def while_statement(self):
247 | self.match("RESERVE_WORD")
248 | self.match("DELIMITER")
249 | condition=self.logical_expression() # 解析循环条件
250 | self.match("DELIMITER")
251 | begin_label = self.get_label()
252 | start_label=self.new_label() # 创建循环开始的标签
253 | #self.quadruples.append((None,None,None,start_label)) # 将标签添加到四元式列表中
254 | self.quadruples.append((start_label,'jfalse',condition,None,None)) # 创建条件跳转的四元式,跳转地址暂时留空
255 | jump_location=len(self.quadruples)-1 # 记录需要回填的四元式的位置
256 | self.match("DELIMITER")
257 | self.statement_list() # 解析循环体中的多条语句
258 | self.match("DELIMITER")
259 | self.quadruples.append((self.new_label(),'jump',None,None,begin_label)) # 创建无条件跳转的四元式
260 | end_label=self.new_label() # 创建循环结束的标签
261 | self.quadruples.append((end_label,None,None,None,end_label)) # 将标签添加到四元式列表中
262 | self.quadruples[jump_location]=(start_label,'jfalse',condition,None,end_label) # 回填跳转地址
263 |
264 | def if_statement(self):
265 | self.match("RESERVE_WORD") # 匹配 "if"
266 | self.match("DELIMITER") # 匹配 "("
267 | condition=self.logical_expression() # 解析 if 条件
268 | self.match("DELIMITER") # 匹配 ")"
269 | start_label = self.new_label()
270 | self.quadruples.append((start_label,'jfalse',condition,None,None)) # 创建条件跳转的四元式,跳转地址暂时留空
271 | jump_location=len(self.quadruples)-1 # 记录需要回填的四元式的位置
272 | self.match("DELIMITER") # 匹配 "{"
273 | self.statement_list() # 解析 if 语句体中的多条语句
274 | self.match("DELIMITER") # 匹配 "}"
275 | end_label=self.new_label() # 创建 if 条件为假时的标签
276 | self.quadruples.append((end_label,'jump',None,None,end_label)) # 创建无条件跳转的四元式,跳转地址暂时留空
277 | jump_location2=len(self.quadruples)-1 # 记录需要回填的四元式的位置
278 | self.quadruples[jump_location]=(start_label,'jfalse',condition,None,end_label) # 回填跳转地址
279 |
280 | # 检查是否有 "else" 或 "else if"
281 | while self.lookahead and self.lookahead[1] in ["else"]:
282 | self.match("RESERVE_WORD") # 匹配 "else"
283 | if self.lookahead and self.lookahead[1]=="if":
284 | self.if_statement() # 如果是 "else if",则递归调用 if_statement 函数
285 | else:
286 | self.match("DELIMITER") # 匹配 "{"
287 | self.statement_list() # 解析 else 语句体中的多条语句
288 | self.match("DELIMITER") # 匹配 "}"
289 | self.quadruples[jump_location2]=(end_label,'jump',None,None,self.new_label()) # 回填跳转地址
290 | self.quadruples.append((self.get_label(),None,None,None,None))
291 | def factor(self):
292 | # 解析因子并返回四元式或常数值
293 | if self.lookahead[0]=="DELIMITER" and self.lookahead[1]=="(":
294 | self.match("DELIMITER")
295 | expr_quad=self.expression()
296 | self.match("DELIMITER")
297 | return expr_quad
298 | elif self.lookahead[0]=="IDENTIFIER":
299 | identifier=self.lookahead[1]
300 | if not self.symbol_table.lookup(identifier): # 检查符号表
301 | raise SyntaxError(f"未声明的变量 '{identifier}' 使用")
302 | self.match("IDENTIFIER")
303 | return identifier # 返回标识符名称
304 | elif self.lookahead[0]=="CONSTANT":
305 | constant_value=self.lookahead[1]
306 | self.match("CONSTANT")
307 | return constant_value # 返回常数值
308 |
309 | def new_temp(self):
310 | # 生成新的临时变量名称
311 | if not hasattr(self,'temp_count'):
312 | self.temp_count=0 # 初始化临时变量计数器
313 | temp_name=f"t{self.temp_count}" # 根据计数器生成临时变量名称
314 | self.temp_count+=1 # 增加计数器
315 | return temp_name # 返回新的临时变量名称
316 |
317 | if __name__ == '__main__':
318 | tokens = [
319 | ('RESERVE_WORD','int'),
320 | ('IDENTIFIER','main'),
321 | ('DELIMITER','('),
322 | ('DELIMITER',')'),
323 | ('DELIMITER','{'),
324 | ('RESERVE_WORD','int'),
325 | ('IDENTIFIER','number'),
326 | ('DELIMITER',';'),
327 | ('RESERVE_WORD','int'),
328 | ('IDENTIFIER','a'),
329 | ('DELIMITER',';'),
330 | ('IDENTIFIER','number'),
331 | ('OPERATOR','='),
332 | ('CONSTANT','10'),
333 | ('DELIMITER',';'),
334 | ('RESERVE_WORD','if'),
335 | ('DELIMITER','('),
336 | ('IDENTIFIER','number'),
337 | ('OPERATOR','>'),
338 | ('CONSTANT','0'),
339 | ('DELIMITER',')'),
340 | ('DELIMITER','{'),
341 | ('IDENTIFIER','a'),
342 | ('OPERATOR','='),
343 | ('IDENTIFIER','number'),
344 | ('DELIMITER',';'),
345 | ('DELIMITER','}'),
346 | ('RESERVE_WORD','else'),
347 | ('DELIMITER','{'),
348 | ('IDENTIFIER','a'),
349 | ('OPERATOR','='),
350 | ('CONSTANT','2'),
351 | ('DELIMITER',';'),
352 | ('DELIMITER','}'),
353 | ('DELIMITER','}')
354 | ]
355 |
356 |
357 |
358 | # 创建解析器实例
359 | parser = Parser(tokens)
360 |
361 | # 开始解析
362 |
363 | parser.program()
364 | print(parser.symbol_table.table)
365 | # 如果没有抛出SyntaxError异常,说明解析成功
366 | print("解析成功!")
367 | print(parser.quadruples)
368 |
--------------------------------------------------------------------------------
/yuyifenxi.py:
--------------------------------------------------------------------------------
1 | ### 中途学习为目的,如果有需要可以实现这个抽象语法树的
2 |
3 | class SemanticAnalyzer:
4 | def __init__(self):
5 | self.symbol_table = {} # 符号表
6 |
7 | def analyze(self, node):
8 | # 根据节点类型进行不同的语义分析
9 | if node.type == 'Assignment':
10 | self.process_assignment(node)
11 | elif node.type == 'BinaryOperation':
12 | self.process_binary_operation(node)
13 | # ... 其他节点类型的处理
14 |
15 | def process_assignment(self,node):
16 | # 处理赋值语句
17 | var_name=node.left.value
18 | var_value=node.right.value
19 | var_type=self.get_type(node.right) # 使用 get_type 方法来确定右侧表达式的类型
20 | if var_name in self.symbol_table:
21 | # 变量已经声明,检查类型等语义规则
22 | expected_type=self.symbol_table[var_name]
23 | if expected_type!=var_type:
24 | raise TypeError(f"变量 '{var_name}' 的类型不匹配: 预期 {expected_type}, 实际 {var_type}")
25 | else:
26 | # 变量未声明,报错或者在符号表中添加新条目
27 | self.symbol_table[var_name]=var_type
28 |
29 | def process_binary_operation(self,node):
30 | # 处理二元运算
31 | left_type=self.get_type(node.left)
32 | right_type=self.get_type(node.right)
33 |
34 | # 类型转换规则
35 | if left_type=='int' and right_type=='float':
36 | left_type='float'
37 | elif left_type=='float' and right_type=='int':
38 | right_type='float'
39 | # 添加更多类型转换规则...
40 |
41 | # 检查转换后的类型是否匹配
42 | if left_type!=right_type:
43 | raise TypeError("类型不匹配")
44 |
45 | # 返回结果类型
46 | return left_type if left_type==right_type else None
47 |
48 | def get_type(self,node):
49 | if node.type=='Variable':
50 | # 如果节点是变量,从符号表中获取类型
51 | var_name=node.value
52 | if var_name in self.symbol_table:
53 | return self.symbol_table[var_name]
54 | else:
55 | raise NameError(f"未声明的变量: {var_name}")
56 | elif node.type=='Constant':
57 | # 如果节点是常量,根据值的类型返回类型
58 | if isinstance(node.value,int):
59 | return 'int'
60 | elif isinstance(node.value,float):
61 | return 'float'
62 | # ... 其他类型的判断
63 |
64 | # 示例:语法树节点
65 | class Node:
66 | def __init__(self, type, value, left=None, right=None):
67 | self.type = type
68 | self.value = value
69 | self.left = left
70 | self.right = right
71 |
72 | # 构建语法树并进行语义分析
73 | assignment_node = Node('Assignment', '=', Node('Variable', 'x'), Node('Constant', 42))
74 | binary_op_node = Node('BinaryOperation', '+', Node('Variable', 'x'), Node('Constant', 3.14))
75 |
76 | semantic_analyzer = SemanticAnalyzer()
77 | semantic_analyzer.analyze(assignment_node)
78 | semantic_analyzer.analyze(binary_op_node)
79 |
80 |
--------------------------------------------------------------------------------
/zhongjiandaima.py:
--------------------------------------------------------------------------------
1 | #同样这里是供自己学习的,目前的compiler并未采用这个,只是用于学习四元式的生成和执行
2 | #四元式的生成在语法分析那里穿插了,解释执行在解释程序那块
3 | # 定义优先级
4 | def precedence(op):
5 | if op == '(':
6 | return 0
7 | elif op in ['+', '-']:
8 | return 1
9 | elif op in ['*', '/']:
10 | return 2
11 | else:
12 | return 3
13 |
14 | # 四元式生成函数
15 | def generate_quadruples(expressions):
16 | temp_count = 1 # 用于生成临时变量
17 | quadruples = [] # 存储生成的四元式
18 | for expr in expressions:
19 | op_stack = [] # 运算符栈
20 | val_stack = [] # 变量栈
21 | for token in expr:
22 | if token.isalpha() or token.isdigit():
23 | val_stack.append(token)
24 | elif token == '(':
25 | op_stack.append(token)
26 | elif token == ')':
27 | while op_stack and op_stack[-1] != '(':
28 | op2 = val_stack.pop()
29 | op1 = val_stack.pop()
30 | op = op_stack.pop()
31 | temp_var = f't{temp_count}'
32 | temp_count += 1
33 | quadruples.append((op, op1, op2, temp_var))
34 | val_stack.append(temp_var)
35 | op_stack.pop() # 弹出 '('
36 | else:
37 | while op_stack and precedence(op_stack[-1]) >= precedence(token):
38 | op2 = val_stack.pop()
39 | op1 = val_stack.pop()
40 | op = op_stack.pop()
41 | temp_var = f't{temp_count}'
42 | temp_count += 1
43 | quadruples.append((op, op1, op2, temp_var))
44 | val_stack.append(temp_var)
45 | op_stack.append(token)
46 | # 处理赋值运算符
47 | if expr[1] == '=':
48 | right_val = val_stack.pop() if val_stack else '_'
49 | left_var = expr[0]
50 | quadruples.append(('=', left_var, '_', right_val))
51 | return quadruples
52 |
53 | # 示例
54 | expressions = [
55 | ['k', '=', 'h'],
56 | ['a', '=', 'b', '+', 'c', '*', 'd'],
57 | ['e', '=', 'f', '/', 'g']
58 | ]
59 | quadruples = generate_quadruples(expressions)
60 | for quad in quadruples:
61 | print(quad)
62 |
--------------------------------------------------------------------------------