├── .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 | 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 | --------------------------------------------------------------------------------