class semantic_action(): def __init__(self,attribute_stack,init_table): self.offset_stack = Stack() self.table_stack = Stack() self.offset_stack.push(0) self.table_stack.push(init_table) self.attribute_stack = attribute_stack self.temp_count = 0 self.code_list = [] self.next_quad = 0 self.param_queue = Queue() self.legal_type = {"float":3,"int":2,"char":1} self.action_array = [self.semantic_action_0,self.semantic_action_1,self.semantic_action_2,self.semantic_action_3,self.semantic_action_4,self.semantic_action_5 ,self.semantic_action_6,self.semantic_action_7,self.semantic_action_8,self.semantic_action_9,self.semantic_action_10 ,self.semantic_action_11,self.semantic_action_12,self.semantic_action_13,self.semantic_action_14,self.semantic_action_15, self.semantic_action_16,self.semantic_action_17,self.semantic_action_18,self.semantic_action_19,self.semantic_action_20, self.semantic_action_21,self.semantic_action_22,self.semantic_action_23,self.semantic_action_24,self.semantic_action_25, self.semantic_action_26,self.semantic_action_27,self.semantic_action_28,self.semantic_action_29,self.semantic_action_30, self.semantic_action_31,self.semantic_action_32,self.semantic_action_33,self.semantic_action_34,self.semantic_action_35, self.semantic_action_36,self.semantic_action_37,self.semantic_action_38,self.semantic_action_39,self.semantic_action_40, self.semantic_action_41,self.semantic_action_42,self.semantic_action_43,self.semantic_action_44,self.semantic_action_45, self.semantic_action_46,self.semantic_action_47,self.semantic_action_48,self.semantic_action_49,self.semantic_action_50, self.semantic_action_51,self.semantic_action_52,self.semantic_action_53,self.semantic_action_54,self.semantic_action_55, self.semantic_action_56,self.semantic_action_57,self.semantic_action_58,self.semantic_action_59,self.semantic_action_60, self.semantic_action_61,self.semantic_action_62,self.semantic_action_63,self.semantic_action_64,self.semantic_action_65, self.semantic_action_66,self.semantic_action_67,self.semantic_action_68] def do_action(self,index): a = self.action_array[index]() #print(self.table_stack.array) #print("do semantic analysis "+str(index)) return a def new_temp(self): result = "$"+str(self.temp_count) self.temp_count += 1 return result def gencode(self,op,first,second,result): self.code_list.append(code(op,first,second,result)) self.next_quad += 1 #{addwidth(top(tblptr),top(offset)); #在外层过程符号表中加入当前过程 #pop(tblptr);pop(offset)} #D::=def X id M1 ( Param ) { W' Z } def semantic_action_5(self): Param = self.attribute_stack.get_top(6) offset = self.offset_stack.get_top() t = self.table_stack.get_top() t.set_offset(offset) name = self.attribute_stack.get_top(9)["addr"] X = self.attribute_stack.get_top(10) Z = self.attribute_stack.get_top(2) if t.duplicate_check(name):#重复定义,程序报错 raise MyException(name+"重复定义") if X["type"] != Z["type"]: raise MyException("返回类型不匹配") t.return_type = X["type"] if t.father_table.duplicate_check(name): raise MyException("函数重复定义") t.father_table.add(symbol_item(name,"fuction",None,t)) t.param_num = Param["param_num"] self.table_stack.pop(1) self.offset_stack.pop(1) return {} #Z::=return E ; #{if 需要返回结果 then gencode(‘:=’, E.addr, -, F); #gencode(‘ret’, -, -, -)} def semantic_action_6(self): Z_attribute = {} E = self.attribute_stack.get_top(2) Z_attribute["type"] = E["type"] self.gencode("=",E["addr"],None,"F") self.gencode("ret",None,None,None) return Z_attribute #M1::=ε def semantic_action_7(self): t = symbol_table(self.table_stack.get_top()) self.table_stack.push(t) self.offset_stack.push(0) return {} #S::=T id ; def semantic_action_10(self): t = self.table_stack.get_top() id_name = self.attribute_stack.get_top(2)["addr"] T_type = self.attribute_stack.get_top(3)["type"] T_width = self.attribute_stack.get_top(3)["width"] offset = self.offset_stack.get_top() if t.duplicate_check(id_name): raise MyException(id_name+"重复定义") else: if "array_dope_vector" in self.attribute_stack.get_top(3):#数组或者正常变量 redundant_point = self.attribute_stack.get_top(3)["array_dope_vector"] if redundant_point != None: redundant_point.address = offset else:#结构体 redundant_point = self.attribute_stack.get_top(3)["table"] t.add(symbol_item(id_name,T_type,offset,redundant_point)) self.offset_stack.pop(1) self.offset_stack.push(offset+T_width) return {} #Param::=T id def semantic_action_11(self): Param_attribute = {} t = self.table_stack.get_top() id_name = self.attribute_stack.get_top(1)["addr"] T_type = self.attribute_stack.get_top(2)["type"] T_width = self.attribute_stack.get_top(2)["width"] offset = self.offset_stack.get_top() if t.duplicate_check(id_name):#重复定义了 raise MyException(id_name+"重复定义") else:#没有重复定义 if "array_dope_vector" in self.attribute_stack.get_top(2):#数组或者正常变量 redundant_point = self.attribute_stack.get_top(2)["array_dope_vector"] if redundant_point != None: redundant_point.address = offset else:#结构体 redundant_point = self.attribute_stack.get_top(2)["table"] t.add(symbol_item(id_name,T_type,offset,redundant_point)) self.offset_stack.pop(1) self.offset_stack.push(offset+T_width) Param_attribute["param_num"] = 1 return Param_attribute #Param::=Param , T id def semantic_action_12(self): Param_attribute = {} Param = self.attribute_stack.get_top(4) t = self.table_stack.get_top() id_name = self.attribute_stack.get_top(1)["addr"] T_type = self.attribute_stack.get_top(2)["type"] T_width = self.attribute_stack.get_top(2)["width"] offset = self.offset_stack.get_top() if t.duplicate_check(id_name): raise MyException(id_name+"重复定义") else: if "array_dope_vector" in self.attribute_stack.get_top(2):#数组或者正常变量 redundant_point = self.attribute_stack.get_top(2)["array_dope_vector"] if redundant_point != None: redundant_point.address = offset else:#结构体 redundant_point = self.attribute_stack.get_top(2)["table"] t.add(symbol_item(id_name,T_type,offset,redundant_point)) self.offset_stack.pop(1) self.offset_stack.push(offset+T_width) Param_attribute["param_num"] = Param["param_num"]+1 return Param_attribute #{T.type := integer; T.width := 4} #X::=int def semantic_action_16(self): X_attribute = {"type":"int","width":4} return X_attribute #X::=float #{T.type :=real; T.width :=8} def semantic_action_17(self): X_attribute = {"type":"float","width":8} return X_attribute #X::=boolean def semantic_action_18(self): X_attribute = {"type":"boolean","width":1} return X_attribute #X::=char def semantic_action_19(self): X_attribute = {"type":"char","width":1} return X_attribute #C::=ε def semantic_action_21(self): C_attribute = {"array_dope_vector":None} return C_attribute #C::=C [ CI ] def semantic_action_20(self): right_C_attribute = self.attribute_stack.get_top(4) left_C_attribute = {} limit = self.attribute_stack.get_top(2)["value"] if right_C_attribute["array_dope_vector"] == None: left_C_attribute["array_dope_vector"] = array_dope_vector(1,(limit,),None,None) else: pre_vector = right_C_attribute["array_dope_vector"] left_C_attribute["array_dope_vector"] = array_dope_vector(pre_vector.dimension+1,pre_vector.limits+(limit,),None,None) return left_C_attribute #T::=X C 生成类型 #{T.type := array(num.val, T1.type);T.width := num.val×X.width}数组 #{T.type := X.type ;T.width := X.width}正常变量 #给符号表准备类型和redunant_point的信息 def semantic_action_13(self): T_attribute = {} vector = self.attribute_stack.get_top(1)["array_dope_vector"] X_attribute = self.attribute_stack.get_top(2) #正常变量 if vector == None: T_attribute["type"] = X_attribute["type"] T_attribute["width"] = X_attribute["width"] T_attribute["array_dope_vector"] = None else:#数组 T_attribute["type"] = "array" total = vector.limits[0] for i in range(1,vector.dimension): total *= vector.limits[i] vector.type = X_attribute["type"] T_attribute["width"] = total * X_attribute["width"] T_attribute["array_dope_vector"] = vector return T_attribute #T → record M2 D end {T.type := record(top(tblptr)); #T.width := top(offset); #pop(tblptr); pop(offset)} #T::=struct { M2 Param } def semantic_action_14(self): T_attribute = {} T_attribute["type"] = "struct" T_attribute["width"] = self.offset_stack.get_top(1) T_attribute["table"] = self.table_stack.get_top(1) self.table_stack.get_top(1).set_offset(self.offset_stack.get_top(1)) self.offset_stack.pop(1) self.table_stack.pop(1) return T_attribute #M2::=ε{t:= mktable(previous); push(t, tblptr); push(0, offset)} def semantic_action_15(self): t = symbol_table(self.table_stack.get_top(1)) self.table_stack.push(t) self.offset_stack.push(0) return {} #{if Left.offset=null then /*Left是简单变量id*/ #gencode(Left.addr ':=' E.addr); #else #gencode(Left.addr '[' Left.offset '] ' ':=' E.addr)} /*Left是数组元素*/ #S::=Left = E ; def semantic_action_24(self): left_offset = self.attribute_stack.get_top(4)["offset"] left_addr = self.attribute_stack.get_top(4)["addr"] E_addr = self.attribute_stack.get_top(2)["addr"] Left = self.attribute_stack.get_top(4) E = self.attribute_stack.get_top(2) if self.attribute_stack.get_top(4)["type"]=="struct": raise MyException("赋值语句类型错误") if not (Left["type"]=="boolean" and E["type"]=="boolean" or Left["type"] in self.legal_type and E["type"] in self.legal_type): raise MyException("赋值类型不匹配") #类型转换 left_type_prioity = self.legal_type[Left["type"]] E_type_prioity = self.legal_type[E["type"]] #如果Left的类型比E宽 if left_type_prioity>E_type_prioity: temp = self.widen(E["addr"],E["type"],Left["type"]) E["addr"] = temp elif left_type_prioity<E_type_prioity: raise MyException("赋值语句不能向宽类型转换") if left_offset == None: self.gencode("=",str(E_addr),None,str(left_addr)) else: self.gencode("=",str(E_addr),None,str(left_addr)+"["+str(left_offset)+"]") return {} #S::=Left = B ; def semantic_action_25(self): left = self.attribute_stack.get_top(4) B = self.attribute_stack.get_top(2) if left["type"]!="boolean": raise MyException("赋值语句类型错误") if left["offset"] == None: result = str(left["addr"]) else: result= str(left["addr"])+"["+str(left["offset"])+"]" self.back_patch(B["truelist"],self.next_quad) self.back_patch(B["falselist"],self.next_quad+2) self.gencode("=","true",None,result) self.gencode("goto",None,None,self.next_quad+2) self.gencode("=","false",None,result) return {} #Left::=id #{Left.addr:=id.addr; Left.offset:=null} #id只能是结构体类型或者一般数据类型,其他的报错。如果正确向上传递类型信息,如果是结构体,那么要传递符号表信息 def semantic_action_26(self): left_attribute = {} t = self.table_stack.get_top(1) id_addr = self.attribute_stack.get_top(1)["addr"] item = t.search(id_addr) if item==None: raise MyException(id_addr+"未定义") if item.type=="fuction" or item.type == "array": raise MyException(id_addr+"类型不匹配") left_attribute["type"] = item.type left_attribute["addr"] = id_addr left_attribute["offset"] = None left_attribute["table"] = item.redundant_point return left_attribute def width(self,array_type): if array_type == "int": return "4" elif array_type == "float": return "8" elif array_type == "char" or array_type == "boolean": return "1" #Left::=L #{ Left.addr:=newtemp; /*Left是数组元素,因此存放基址和位移*/ #Left.offset:=newtemp; #gencode(Left.addr ':=' c(L.array)); #gencode(Left.offset ':=' L.addr '*' width(L.array))} #L的类型必须是基本类型,而不是array def semantic_action_27(self): left_attribute = {} left_attribute["addr"] = self.new_temp() left_attribute["offset"] = self.new_temp() l_array = self.attribute_stack.get_top(1)["array"] l_addr = self.attribute_stack.get_top(1)["addr"] L = self.attribute_stack.get_top(1) if L["type"]=="array": raise MyException("数组索引过少") left_attribute["type"] = L["type"] self.gencode("=",str(l_array.address),None,left_attribute["addr"]) self.gencode("*",l_addr,self.width(l_array.type),left_attribute["offset"]) return left_attribute #Left::=Left1 . id #最终推到出的形式为struct.struct.struct.id或者struct.struct.struct.L #右部 left 有 addr 和 offset addr存的是结构体的复合名字 offset存的是数组的偏移量 #Left.addr:=id.name+Left1.addr /*Left是数组元素,因此存放基址和位移*/ #Left.offset:=Left1.addr #Left的类型只能是结构体,其他的报错。id的类型是结构体或者是一般类型否则报错,但是id不可能为函数,因为定义语句不允许 # ,如果是结构体要传递符号表信息 def semantic_action_28(self): left_attribute = {} id_name = self.attribute_stack.get_top(1)["addr"] Left1 = self.attribute_stack.get_top(3) t = Left1["table"] item = t.search(id_name) if item == None: raise MyException(id_name+"未定义") if Left1["type"] != "struct": raise MyException("不能对非结构体进行.操作") if item.type == "struct": left_attribute["table"] = item.redundant_point left_attribute["type"] = item.type left_attribute["addr"] = id_name +"."+self.attribute_stack.get_top(3)["addr"] left_attribute["offset"] = self.attribute_stack.get_top(3)["offset"] return left_attribute #L::=id [ E ] #{L.array:=id.addr; L.addr:= E.addr; L.ndim:=1} #array用来存内情向量表 #数组id的addr为内情向量 def semantic_action_29(self): L_attribute = {} t = self.table_stack.get_top(1) id_name = self.attribute_stack.get_top(4)["addr"] item = t.search(id_name) E = self.attribute_stack.get_top(2) if item == None: raise MyException(id_name+"未定义") if item.type != "array": raise MyException(id_name+"非数组变量不能有索引") if E["type"] != "int": raise MyException("数组索引只能用整数") L_attribute["array"] = self.table_stack.get_top(1).search(id_name).redundant_point L_attribute["addr"] = self.attribute_stack.get_top(2)["addr"] L_attribute["ndim"] = 0 if len(L_attribute["array"].limits) == 1: L_attribute["type"] = L_attribute["array"].type else: L_attribute["type"] = "array" return L_attribute #{t:=newtemp; # m:= L1.ndim+1; #gencode(t ':=' L1.addr '*' limit(L1.array, m)); /*计算em-1×nm */ #gencode(t ':=' t '+' E.addr); /* 计算+ im */ #L.array:= L1.array; #L.addr:=t; #L.ndim:=m} #L::=L1 [ E ] def semantic_action_30(self): L_attribute = {} t = self.new_temp() m = self.attribute_stack.get_top(4)["ndim"]+1 L1 = self.attribute_stack.get_top(4) E = self.attribute_stack.get_top(2) if L1["type"]!="array": raise MyException("数组索引过多") self.gencode("*",L1["addr"],L1["array"].limits[m],t) self.gencode("+",t,E["addr"],t) L_attribute["array"] = L1["array"] L_attribute["addr"] = t L_attribute["ndim"] = m if m==len(L1["array"].limits)-1: L_attribute["type"] = L1["array"].type else: L_attribute["type"] = "array" return L_attribute #E::=E1 + Y #{E.addr:=newtemp;gencode(E.addr ':='E1.addr'+'Y.addr)} def semantic_action_31(self): E_attribute = {} E_attribute["addr"] = self.new_temp() E1 = self.attribute_stack.get_top(3) Y = self.attribute_stack.get_top(1) if Y["type"] not in self.legal_type: raise MyException("算数类型不对") if E1["type"] not in self.legal_type: raise MyException("算数类型不对") E_attribute["type"] = self.max_type(E1["type"],Y["type"]) a1 = self.widen(E1["addr"],E1["type"],E_attribute["type"]) a2 = self.widen(Y["addr"],Y["type"],E_attribute["type"]) self.gencode("+",a1,a2,E_attribute["addr"]) return E_attribute #E::=E1 - Y #{E.addr:=newtemp;gencode(E.addr ':='E1.addr'-'Y.addr)} def semantic_action_32(self): E_attribute = {} E_attribute["addr"] = self.new_temp() E1 = self.attribute_stack.get_top(3) Y = self.attribute_stack.get_top(1) if E1["type"] not in self.legal_type: raise MyException("算数类型不对") if Y["type"] not in self.legal_type: raise MyException("算数类型不对") E_attribute["type"] = self.max_type(E1["type"],Y["type"]) a1 = self.widen(E1["addr"],E1["type"],E_attribute["type"]) a2 = self.widen(Y["addr"],Y["type"],E_attribute["type"]) self.gencode("-",a1,a2,E_attribute["addr"]) return E_attribute #E::=Y #{E.addr:=Y.addr} def semantic_action_33(self): E_attribute = {} E_attribute["addr"] = self.attribute_stack.get_top(1)["addr"] E_attribute["type"] = self.attribute_stack.get_top(1)["type"] return E_attribute #Y::=Y1 * F #{Y.addr:=newtemp;gencode(Y.addr ':='Y1.addr'*'F.addr)} def semantic_action_34(self): Y_attribute = {} Y_attribute["addr"] = self.new_temp() Y1 = self.attribute_stack.get_top(3) F = self.attribute_stack.get_top(1) if F["type"] not in self.legal_type: raise MyException("算数类型不对") if Y1["type"] not in self.legal_type: raise MyException("算数类型不对") Y_attribute["type"] = self.max_type(Y1["type"],F["type"]) a1 = self.widen(Y1["addr"],Y1["type"],Y_attribute["type"]) a2 = self.widen(F["addr"],F["type"],Y_attribute["type"]) self.gencode("*",a1,a2,Y_attribute["addr"]) return Y_attribute #Y::=Y1 / F #{Y.addr:=newtemp;gencode(Y.addr ':='Y1.addr'/'F.addr)} def semantic_action_35(self): Y_attribute = {} Y_attribute["addr"] = self.new_temp() Y1 = self.attribute_stack.get_top(3) F = self.attribute_stack.get_top(1) if F["type"] not in self.legal_type: raise MyException("算数类型不对") if Y1["type"] not in self.legal_type: raise MyException("算数类型不对") Y_attribute["type"] = self.max_type(Y1["type"],F["type"]) a1 = self.widen(Y1["addr"],Y1["type"],Y_attribute["type"]) a2 = self.widen(F["addr"],F["type"],Y_attribute["type"]) self.gencode("/",a1,a2,Y_attribute["addr"]) return Y_attribute #Y::=F #{Y.addr:=F.addr} def semantic_action_36(self): Y_attribute = {} Y_attribute["addr"] = self.attribute_stack.get_top(1)["addr"] Y_attribute["type"] = self.attribute_stack.get_top(1)["type"] return Y_attribute #F::=( M ) #{F.addr:=M.addr} def semantic_action_37(self): F_attribute = {} F_attribute["addr"] = self.attribute_stack.get_top(2)["addr"] F_attribute["type"] = self.attribute_stack.get_top(2)["type"] return F_attribute #F::=M #F.addr:=M.addr def semantic_action_38(self): F_attribute = {} F_attribute["addr"] = self.attribute_stack.get_top(1)["addr"] F_attribute["type"] = self.attribute_stack.get_top(1)["type"] return F_attribute #{if Left.offset=null then /*Left是简单id*/ #M.addr:= Left.addr #else begin /*Left是数组元素*/ #M.addr:=newtemp; #gencode(M.addr ':=' Left.addr ' [' Left.offset ']') #end} #M::=Left #Left只能是一般类型,不能是结构体。Left一定不是数组类型Left::=L的时候已经检查了 def semantic_action_39(self): M_attribute = {} Left = self.attribute_stack.get_top(1) if Left["type"] not in {"char","int","float","boolean"}: raise MyException("类型错误") if Left["offset"] == None: M_attribute["addr"] = Left["addr"] else: M_attribute["addr"] = self.new_temp() self.gencode("=",Left["addr"] + "[" + Left["offset"] + "]",None,M_attribute["addr"]) M_attribute["type"] = Left["type"] return M_attribute #M::=CI #M.addr:=newtemp; #gencode(M.addr ':=' CI) def semantic_action_40(self): M_attribute = {} M_attribute["addr"] = self.new_temp() M_attribute["type"] = "int" CI = self.attribute_stack.get_top(1) self.gencode("=",str(CI["value"]),None,M_attribute["addr"]) return M_attribute #M::=CF #M.addr:=newtemp; #gencode(M.addr ':=' CF) def semantic_action_41(self): M_attribute = {} M_attribute["addr"] = self.new_temp() M_attribute["type"] = "float" CF = self.attribute_stack.get_top(1) self.gencode("=",str(CF["value"]),None,M_attribute["addr"]) return M_attribute #M::=CC #M.addr:=newtemp; #gencode(M.addr ':=' CC) def semantic_action_42(self): M_attribute = {} M_attribute["addr"] = self.new_temp() M_attribute["type"] = "char" CC = self.attribute_stack.get_top(1) self.gencode("=",str(CC["value"]),None,M_attribute["addr"]) return M_attribute def back_patch(self,code_index_list,quad): for index in code_index_list: self.code_list[index].result = quad def merge(self,list1,list2): return list1+list2 def makelist(self,quad): return [quad] #{backpatch(B.truelist, M3.quad); #S.nextlist := merge(B.falselist, W'.nextlist)} #S::= if B { M3 W' } def semantic_action_43(self): S_attribute = {} B = self.attribute_stack.get_top(5) M3 = self.attribute_stack.get_top(3) W_ = self.attribute_stack.get_top(2) self.back_patch(B["truelist"],M3["quad"]) S_attribute["nextlist"] = self.merge(B["falselist"],W_["nextlist"]) return S_attribute #{backpatch(B.truelist, M31.quad); #backpatch(B.falselist, M32.quad); #S.nextlist := merge(W'1.nextlist, merge(M4.nextlist, W'2.nextlist))} #S::= if B { M31 W'1 } M4 else { M32 W'2 } def semantic_action_44(self): S_attribute = {} B = self.attribute_stack.get_top(11) M31 = self.attribute_stack.get_top(9) M32 = self.attribute_stack.get_top(3) W_1 = self.attribute_stack.get_top(8) W_2 = self.attribute_stack.get_top(2) M4 = self.attribute_stack.get_top(6) self.back_patch(B["truelist"],M31["quad"]) self.back_patch(B["falselist"],M32["quad"]) S_attribute["nextlist"] = self.merge(W_1["nextlist"],self.merge(M4["nextlist"],W_2["nextlist"])) return S_attribute #{backpatch(W'.nextlist, M31.quad); #backpatch(B.truelist,M32.quad); #S.nextlist:=B.falselist; #gencode('goto'M31.quad)} #S::= while M31 B do { M32 W' } def semantic_action_45(self): S_attribute = {} W_ = self.attribute_stack.get_top(2) M32 = self.attribute_stack.get_top(3) B = self.attribute_stack.get_top(6) M31 = self.attribute_stack.get_top(7) self.back_patch(W_["nextlist"],M31["quad"]) self.back_patch(B["truelist"],M32["quad"]) S_attribute["nextlist"] = B["falselist"] self.gencode("goto",None,None,M31["quad"]) return S_attribute #{M.quad := nextquad} #M3::=ε def semantic_action_46(self): M3_attirbute = {} M3_attirbute["quad"] = self.next_quad return M3_attirbute #{M4.nextlist := makelist(nextquad); gencode('goto –')} #M4::=ε def semantic_action_47(self): M4_attribute = {} M4_attribute["nextlist"] = self.makelist(self.next_quad) self.gencode("goto",None,None,None) return M4_attribute #{ backpatch(B1.falselist, M3.quad); #B.truelist := merge(B1.truelist, G.truelist); #B.falselist := G.falselist} #B::=B1 || M3 G def semantic_action_48(self): B_attribute = {} B1 = self.attribute_stack.get_top(4) M3 = self.attribute_stack.get_top(2) G = self.attribute_stack.get_top(1) self.back_patch(B1["falselist"],M3["quad"]) B_attribute["truelist"] = self.merge(B1["truelist"],G["truelist"]) B_attribute["falselist"] = G["falselist"] return B_attribute #B.truelist = G.truelist #B.falselist = G.falselist #B::=G def semantic_action_49(self): B_attribute = {} G = self.attribute_stack.get_top(1) B_attribute["truelist"] = G["truelist"] B_attribute["falselist"] = G["falselist"] return B_attribute #{backpatch(G1.truelist, M3.quad); #G.truelist := H.truelist; #G.falselist := merge(G1.falselist, H.falselist)} #G::=G1 && M3 H def semantic_action_50(self): G_attribute = {} G1 = self.attribute_stack.get_top(4) M3 = self.attribute_stack.get_top(2) H = self.attribute_stack.get_top(1) self.back_patch(G1["truelist"],M3["quad"]) G_attribute["truelist"] = H["truelist"] G_attribute["falselist"] = self.merge(G1["falselist"],H["falselist"]) return G_attribute #G.truelist = H.truelist #G.falselist = H.falselist #G::=H def semantic_action_51(self): G_attribute = {} H = self.attribute_stack.get_top(1) G_attribute["truelist"] = H["truelist"] G_attribute["falselist"] = H["falselist"] return G_attribute #H.truelist := H1.falselist; H.falselist := H1.truelist #H::=! H1 def semantic_action_52(self): H_attribute = {} H1 = self.attribute_stack.get_top(1) H_attribute["truelist"] = H1["falselist"] H_attribute["falselist"] = H1["truelist"] return H_attribute #H.truelist = I.truelist #H.falselist = I.falselist #H::=I def semantic_action_53(self): H_attribute = {} I = self.attribute_stack.get_top(1) H_attribute["truelist"] = I["truelist"] H_attribute["falselist"] = I["falselist"] return H_attribute #{I.truelist :=makelist(nextquad); #I.falselist := makelist(nextquad+1); #gencode('if' E1.addr R.op E2.addr 'goto –'); #gencode('goto –')} #I::=E1 R E2 def semantic_action_54(self): I_attribute = {} E2 = self.attribute_stack.get_top(1) R = self.attribute_stack.get_top(2) E1 = self.attribute_stack.get_top(3) I_attribute["truelist"] = self.makelist(self.next_quad) I_attribute["falselist"] = self.makelist(self.next_quad+1) self.gencode("goto"+R["op"],E1["addr"],E2["addr"],None) self.gencode("goto",None,None,None) return I_attribute #I.truelist := B.truelist; #I.falselist := B.falselist #I::=( B ) def semantic_action_55(self): I_attribute = {} B = self.attribute_stack.get_top(2) I_attribute["truelist"] = B["truelist"] I_attribute["falselist"] = B["falselist"] return I_attribute #I::=true #I.truelist := makelist(nextquad); #gencode('goto –') def semantic_action_56(self): I_attribute = {} I_attribute["truelist"] = self.makelist(self.next_quad) I_attribute["falselist"] = [] self.gencode("goto",None,None,None) return I_attribute #I.falselist := makelist(nextquad); # gencode('goto –') #I::=false def semantic_action_57(self): I_attribute = {} I_attribute["falselist"] = self.makelist(self.next_quad) I_attribute["truelist"] = [] self.gencode("goto",None,None,None) return I_attribute #R.op = "<" #R::=< def semantic_action_58(self): R_attribute = {"op":"<"} return R_attribute #R.op = "<=" #R::=< = def semantic_action_59(self): R_attribute = {"op":"<="} return R_attribute #R.op = "==" #R::== = def semantic_action_60(self): R_attribute = {"op":"=="} return R_attribute #R.op = "! =" #R::=! = def semantic_action_61(self): R_attribute = {"op":"!="} return R_attribute #R.op = ">" #R::=> def semantic_action_62(self): R_attribute = {"op":">"} return R_attribute #R.op = ">=" #R::=> = def semantic_action_63(self): R_attribute = {"op":">="} return R_attribute #{backpatch(W'1.nextlist, M3.quad); #W'.nextlist = S.nextlist if S has nextlist #or W'.nextlist = [] #W'::=W'1 M3 S def semantic_action_9(self): W__attribute = {} W_1 = self.attribute_stack.get_top(3) M3 = self.attribute_stack.get_top(2) S = self.attribute_stack.get_top(1) self.back_patch(W_1["nextlist"],M3["quad"]) if "nextlist" in S: W__attribute["nextlist"] = S["nextlist"] else: W__attribute["nextlist"] = [] return W__attribute #W'.nextlist = S.nextlist if S has nextlist #or W'.nextlist = [] #W'::=S def semantic_action_8(self): W__attribute = {} S = self.attribute_stack.get_top(1) if "nextlist" in S: W__attribute["nextlist"] = S["nextlist"] else: W__attribute["nextlist"] = [] return W__attribute #P.nextlist = S.nextlist if S has nextlist #or P.nextlist = [] #P::=S def semantic_action_4(self): P_attribute = {} S = self.attribute_stack.get_top(1) if "nextlist" in S: P_attribute["nextlist"] = S["nextlist"] else: P_attribute["nextlist"] = [] return P_attribute #P.nextlist = [] #P::=D def semantic_action_3(self): P_attribute = {} P_attribute["nextlist"] = [] return P_attribute #P'::=P #P'.nextlist = P.nextlist def semantic_action_2(self): P__attribute = {} P = self.attribute_stack.get_top(1) P__attribute["nextlist"] = P["nextlist"] return P__attribute #P'::=P'1 M3 P #{backpatch(P'1.nextlist, M3.quad); #P'.nextlist = P.nextlist def semantic_action_1(self): P__attribute = {} P = self.attribute_stack.get_top(1) M3 = self.attribute_stack.get_top(2) P_1 = self.attribute_stack.get_top(3) self.back_patch(P_1["nextlist"],M3["quad"]) P__attribute["nextlist"] = P["nextlist"] return P__attribute #start::=P' def semantic_action_0(self): return {} # {n :=0; #repeat #n:=n+1; #从queue的队首取出一个实参地址p; #gencode('param', -, -, p); #until queue为空; #gencode('call', id.addr, n, -)} #S::=Left = call id ( Elist ) ; #要检查参数数目和类型 def semantic_action_64(self): t = self.table_stack.get_top(1) id = self.attribute_stack.get_top(5) Elist = self.attribute_stack.get_top(3) Left = self.attribute_stack.get_top(8) item = t.search(id["addr"]) n=0 if item==None: raise MyException(id["addr"]+"未定义") table = item.redundant_point if item.type!="fuction": raise MyException("不能对非函数变量进行函数调用") if table.param_num != len(Elist["type_array"]): raise MyException("参数个数不正确") for i in range(table.param_num): if table.table[i].type != Elist["type_array"][i]: raise MyException("第"+str(i+1)+"个参数类型不正确") if not (Left["type"]=="boolean" and table.return_type=="boolean" or Left["type"] in self.legal_type and table.return_type in self.legal_type): raise MyException("赋值类型不匹配") #类型转换 left_type_prioity = self.legal_type[Left["type"]] E_type_prioity = self.legal_type[table.return_type] #如果Left的类型比E宽 if left_type_prioity>E_type_prioity: temp = self.widen(table.return_type,table.return_type,Left["type"]) table.return_type = temp elif left_type_prioity<E_type_prioity: raise MyException("赋值语句不能向宽类型转换") while not self.param_queue.is_empty(): p = self.param_queue.dequeue() self.gencode("param",None,None,p) n+=1 self.gencode("call",id["addr"],n,None) self.gencode("=","F",None,Left["addr"]) return {} #Elist::=Elist , E #{将E.addr添加到queue的队尾} def semantic_action_65(self): Elist_attribute = {} E = self.attribute_stack.get_top(1) Elist = self.attribute_stack.get_top(3) self.param_queue.enqueue(E["addr"]) Elist_attribute["type_array"] = Elist["type_array"] + [E["type"]] return Elist_attribute #Elist::=E #初始化queue,然后将E.addr加入到queue的队尾。 #记录E的类型,用于对比实参和形参类型 def semantic_action_66(self): Elist_attribute = {} self.param_queue = Queue() E = self.attribute_stack.get_top(1) self.param_queue.enqueue(E["addr"]) Elist_attribute["type_array"] = [E["type"]] return Elist_attribute #List::=id def semantic_action_68(self): self.param_queue = Queue() id = self.attribute_stack.get_top(1) t = self.table_stack.get_top(1) if t.search(id["addr"])==None: raise MyException(id["addr"]+"未定义") self.param_queue.enqueue(id["addr"]) return {} #List::=List , id ##{将id.addr添加到queue的队尾} def semantic_action_67(self): id = self.attribute_stack.get_top(1) t = self.table_stack.get_top(1) if t.search(id["addr"])==None: raise MyException(id["addr"]+"未定义") self.param_queue.enqueue(id["addr"]) return {} #{n:=0; #repeat #move(Queue, in); #gencode(‘param’, -, -, in); #n:=n+1; #until Queue为空; #gencode(‘call’, ‘SYSOUT’, n, -)} #S::=print ( Elist ) ; def semantic_action_22(self): n = 0 while not self.param_queue.is_empty(): p = self.param_queue.dequeue() self.gencode("param",None,None,p) n = n+1 self.gencode("call","SYSOUT",n,None) return {} #{n:=0; #repeat #move(Queue, in); #gencode(‘par’, ‘in’, -, -); #n:=n+1; #until Queue为空; #gencode(‘call’, ‘SYSIN’, n, -);} #S::=input ( List ) ; def semantic_action_23(self): n = 0 while not self.param_queue.is_empty(): p = self.param_queue.dequeue() self.gencode("param",None,None,p) n = n+1 self.gencode("call","SYSIN",n,None) return {} def max_type(self,type1,type2): legal_type = self.legal_type if type1 not in legal_type or type2 not in legal_type: raise MyException("算数运算类型不正确") type1_prioity = legal_type[type1] type2_prioity = legal_type[type2] if type1_prioity>type2_prioity: return type1 else: return type2 def widen(self,addr,init_type,wide_type): init_type_prioity = self.legal_type[init_type] wide_type_prioity = self.legal_type[wide_type] if init_type_prioity==wide_type_prioity: return addr elif init_type_prioity<wide_type_prioity: temp = self.new_temp() self.gencode(init_type+"to"+wide_type,addr,None,temp) return temp
class grammar_parser(): def __init__(self, path): self.terminators = set() self.variable = set() self.null_symbol = set("ε") self.expression = [] self.first_dict = {} self.all_clourse = [] self.map_of_clourses = {} self.action = [] self.goto = [] self.follow_dict = {} self.symbol_stack = None self.state_stack = None self.type_code = None self.token_list = None self.attribute_stack = Stack() self.name_map = {} self.init_table = symbol_table(None) self.no_error_flag = True self.semantic_action = semantic_action(self.attribute_stack, self.init_table) self.code_file = open("intermediate_code.txt", "w") with open(path, "r") as g: g.readline() state = 1 for line in g.readlines(): line = line.strip() if line == "Variable": state = 2 continue if line == "Expression": state = 3 continue if state == 1: ts = line.split() for t in ts: assert t not in self.terminators self.terminators.add(t) if "id" in line: self.name_map["1"] = ts[0] self.name_map["2"] = ts[1] self.name_map["3"] = ts[2] self.name_map["5"] = ts[3] elif state == 2: assert line.split("#")[0] not in self.variable self.variable.add(line.split("#")[0]) elif state == 3: if line == "": continue temp_variable, right_side = line.split("::=") for a in right_side.split(): assert a in self.terminators or a in self.variable or a == "ε" assert temp_variable in self.variable if right_side == "ε": self.expression.append( Expression(temp_variable, tuple())) else: self.expression.append( Expression(temp_variable, tuple(right_side.split()))) self.first_set_for_char() self.get_all_clourse() self.get_table() self.get_follow() def show_symbol_table(self): table = self.init_table q = Queue() q.enqueue(table) i = 0 while not q.is_empty(): table = q.dequeue() print("符号表" + str(i), table.offset, table.father_table) i += 1 for item in table.table: if item.type == "fuction" or item.type == "record": q.enqueue(item.redundant_point) if item.type == "array": item.show_item("\t") item.redundant_point.show_vector() else: item.show_item() def get_follow(self): for a in self.variable: self.follow_dict[a] = set() self.follow_dict["start"] = set(["#"]) while True: stable = True for e in self.expression: for i in range(len(e.rightside)): char = e.rightside[i] if char in self.variable: if i == len( e.rightside) - 1 and char != e.leftside and ( self.follow_dict[e.leftside] - self.follow_dict[char]) != set(): self.follow_dict[char] = self.follow_dict[ char] | self.follow_dict[e.leftside] stable = False elif i != len(e.rightside) - 1: first_beta = self.first_set_for_string( e.rightside[i + 1:]) if ((first_beta - set(["ε"])) - self.follow_dict[char]) != set(): self.follow_dict[char] = self.follow_dict[ char] | (first_beta - set(["ε"])) stable = False if "ε" in first_beta and char != e.leftside and ( self.follow_dict[e.leftside] - self.follow_dict[char]) != set(): self.follow_dict[char] = self.follow_dict[ char] | self.follow_dict[e.leftside] stable = False if stable: break for v in self.follow_dict: assert "ε" not in self.follow_dict[v] def first_set_for_char(self): for char in self.terminators: self.first_dict[char] = set([char]) for char in self.variable: self.first_dict[char] = set() while True: stable = True for e in self.expression: if len(e.rightside) == 0 and "ε" not in self.first_dict[ e.leftside]: self.first_dict[e.leftside].add("ε") stable = False else: for i in range(len(e.rightside)): if e.rightside[i] in self.variable: if len((self.first_dict[e.rightside[i]] - set(["ε"])) - self.first_dict[e.leftside]) > 0: self.first_dict[e.leftside] = self.first_dict[ e.leftside] | ( self.first_dict[e.rightside[i]] - set(["ε"])) stable = False elif e.rightside[i] in self.terminators and e.rightside[ i] not in self.first_dict[e.leftside]: self.first_dict[e.leftside].add(e.rightside[i]) stable = False if i == len(e.rightside) - 1 and "ε" in self.first_dict[ e.rightside[i]] and "ε" not in self.first_dict[ e.leftside]: self.first_dict[e.leftside].add("ε") stable = False if "ε" not in self.first_dict[e.rightside[i]]: break if stable: break def first_set_for_string(self, string): first = set() if string == ["ε"] or string == []: first.add("ε") return first else: for i in range(len(string)): item = string[i] first = first | (self.first_dict[item] - set("ε")) if i == len(string) - 1 and "ε" in self.first_dict[item]: first.add("ε") if "ε" not in self.first_dict[item]: break return first def is_not_specified(self, item): if item.loc_of_point >= len(item.rightside): return False return True def get_clourse(self, I): clourse_set = set(I) while True: temp_set = set() for item in clourse_set: if self.is_not_specified(item) and item.rightside[ item.loc_of_point] in self.variable: all_char = self.first_set_for_string( item.rightside[item.loc_of_point + 1:] + (item.ex_symbol, )) for e in self.expression: if e.leftside == item.rightside[item.loc_of_point]: for c in all_char: new_item = Item(e.leftside, e.rightside, 0, c) if new_item not in clourse_set: temp_set.add(new_item) if temp_set: clourse_set = clourse_set | temp_set else: break return clourse_set def Go(self, I, X): assert X != "ε" successive_item_set = set() for item in I: if self.is_not_specified(item) and item.rightside[ item.loc_of_point] == X: successive_item_set.add( Item(item.leftside, item.rightside, item.loc_of_point + 1, item.ex_symbol)) return self.get_clourse(successive_item_set) def get_all_clourse(self): queue = Queue() all_clourse = self.all_clourse queue.enqueue( self.get_clourse([ Item(self.expression[0].leftside, self.expression[0].rightside, 0, "#") ])) i = 0 while not queue.is_empty(): current = queue.dequeue() all_clourse.append(current) current_index = len(all_clourse) - 1 self.map_of_clourses[current_index] = {} for x in sorted(list(self.terminators | self.variable)): next = self.Go(current, x) if next != set( ) and next not in self.all_clourse and not queue.In( next): #next不为空,并且不在队列中,也不在all_clourse中 queue.enqueue(next) i += 1 if next in self.all_clourse: self.map_of_clourses[current_index][ x] = self.all_clourse.index(next) elif queue.In(next): self.map_of_clourses[current_index][x] = len( self.all_clourse) + queue.index(next) def find_expression(self, item): for i in range(len(self.expression)): e = self.expression[i] if e.rightside == item.rightside and e.leftside == item.leftside: return i return -1 def get_table(self): self.action = [] self.goto = [] for i in range(len(self.all_clourse)): self.action.append({}) self.goto.append({}) for i in range(len(self.all_clourse)): for char in self.map_of_clourses[i]: if char in self.terminators: self.action[i][char] = self.map_of_clourses[i][char] elif char in self.variable: self.goto[i][char] = self.map_of_clourses[i][char] for item in self.all_clourse[i]: if item.loc_of_point == len(item.rightside): index = self.find_expression(item) if index == 0 and item.ex_symbol == "#": assert "#" not in self.action[i] self.action[i]["#"] = "acc" else: if item.ex_symbol in self.action[i]: print(item, "r" + str(index), self.action[i][item.ex_symbol]) assert item.ex_symbol not in self.action[i] self.action[i][item.ex_symbol] = "r" + str(index) print("文法无冲突") def grammar_parse(self, verbose=True): self.symbol_stack = Stack() self.state_stack = Stack() self.symbol_stack.push("#") self.state_stack.push(0) expression_file = open("规约过程.txt", "w") index = 0 while True: try: top_state = self.state_stack.get_top() char = self.token_list[index] command = self.action[top_state][char] if isinstance(command, int): #读入动作 self.state_stack.push(command) self.symbol_stack.push(char) if char == "id": self.attribute_stack.push( {"addr": self.init_token_list[index]}) elif char in {"<", "<=", "!=", "==", ">", ">="}: self.attribute_stack.push({"op": char}) elif char == "CI": self.attribute_stack.push( {"value": int(self.init_token_list[index])}) elif char == "CF": self.attribute_stack.push( {"value": float(self.init_token_list[index])}) elif char == "CC": self.attribute_stack.push( {"value": self.init_token_list[index]}) else: self.attribute_stack.push( {"row_num": self.type_code[index][2]}) index += 1 elif command == "acc": #接受动作 for i in range(len(self.semantic_action.code_list)): self.code_file.write( str(i) + ":" + self.semantic_action.code_list[i].toString() + "\n") break else: #规约动作 e = self.expression[int(command[1:])] #规约前执行语义动作 new_attribute = self.semantic_action.do_action( int(command[1:])) #规约 self.state_stack.pop(len(e.rightside)) self.symbol_stack.pop(len(e.rightside)) self.attribute_stack.pop(len(e.rightside)) self.symbol_stack.push(e.leftside) top_state = self.state_stack.get_top() self.state_stack.push(self.goto[top_state][e.leftside]) self.attribute_stack.push(new_attribute) #输出序列 if verbose: if e.rightside: expression_file.write(e.leftside + "::=" + "".join(e.rightside) + "\n") else: expression_file.write(e.leftside + "::=" + "".join(e.rightside + ("ε", )) + "\n") #print(self.symbol_stack.array)#打印符号栈 #print(self.attribute_stack.array) except (KeyError, MyException) as e: #语义分析是行数减一 if type(e) == KeyError: print("Error at Line [" + str(self.type_code[index][2]) + "]:[the error is near \"" + self.init_token_list[index] + "\"]") elif type(e) == MyException: print("Error at Line [" + str(int(self.type_code[index][2]) - 1) + "]:[" + str(e) + "]") while True: top_state = self.state_stack.get_top() if "P" in self.goto[top_state]: break self.state_stack.pop(1) s = self.symbol_stack.pop(1) self.attribute_stack.pop(1) if s == ["struct"] or s == ["def"]: self.semantic_action.table_stack.get_top(1).set_offset( self.semantic_action.offset_stack.get_top(1)) self.semantic_action.table_stack.pop(1) self.semantic_action.offset_stack.pop(1) state = self.goto[top_state]["P"] #压入栈的状态 self.state_stack.push(state) self.symbol_stack.push("P") self.attribute_stack.push({"nextlist": []}) while True: char = self.token_list[index] if char not in self.follow_dict["P"]: index += 1 if index >= len(self.token_list): index = len(self.token_list) - 1 break else: break expression_file.close() def show_table(self, verbose=False): sorted_terminators = sorted(list(self.terminators)) sorted_variable = sorted(list(self.variable)) with open("LR(1)分析表.txt", "w") as l: if verbose: """for i in range(len(self.all_clourse)): sorted_expression = sorted(list(self.all_clourse[i])) for item in sorted_expression: temp_list = list(item.rightside) temp_list.insert(item.loc_of_point,".") print(item.leftside+"::="+"".join(temp_list)+"\t"+item.ex_symbol)""" l.write("\t\t" + "\t\t".join(sorted_terminators) + "\t\t" + "\t\t".join(sorted_variable) + "\n") for i in range(len(self.all_clourse)): l.write(str(i) + "\t\t") for char in sorted_terminators: if char in self.action[i]: if type(self.action[i][char]) == str: l.write(str(self.action[i][char]) + "\t\t") else: l.write("S" + str(self.action[i][char]) + "\t\t") else: l.write("\t\t") for char in sorted_variable: if char in self.goto[i]: l.write(str(self.goto[i][char]) + "\t\t") else: l.write("\t\t") l.write("\n") l.write("状态数" + str(len(self.all_clourse))) def read_tokens(self): self.type_code = [] self.token_list = [] self.init_token_list = [] with open("token.txt", "r") as t: lines = t.readlines() for line in lines: token, type_code = line.strip().split() type_code = tuple(type_code[1:len(type_code) - 1].split(",")) if type_code[0] in self.name_map: self.token_list.append(self.name_map[type_code[0]]) else: self.token_list.append(token) self.init_token_list.append(token) self.type_code.append(type_code) self.token_list.append("#") self.init_token_list.append("#") self.type_code.append((None, None, self.type_code[-1][2]))