import os import sys import dataclasses from lex_c import lex_token from lex_c import lex import lex_c _NodeTypeTable=[ "file","vdecl","fdef" ] @dataclasses.dataclass class node: name:list[str]=dataclasses.field(default_factory=list) type:str="base" token_list:list[lex_token]=dataclasses.field(default_factory=list) child:list=dataclasses.field(default_factory=list) def complite(self): print(f"complite {self.type}") # 文件节点 @dataclasses.dataclass class node_file(node): type:str="file" # 变量定义节点 @dataclasses.dataclass class node_variable_def(node): type:str="variable_def" # 结构体声明节点 @dataclasses.dataclass class node_struct_decl(node): type:str="struct_decl" # 结构体定义节点 @dataclasses.dataclass class node_struct_def(node): type:str="struct_def" # 联合体声明节点 @dataclasses.dataclass class node_union_decl(node): type:str="union_decl" # 联合体定义节点 @dataclasses.dataclass class node_union_def(node): type:str="union_def" # 枚举声明节点 @dataclasses.dataclass class node_enum_decl(node): type:str="enum_decl" # 枚举定义节点 @dataclasses.dataclass class node_enum_def(node): type:str="enum_def" # 函数声明节点 @dataclasses.dataclass class node_func_decl(node): type:str="func_decl" #typedef 节点 @dataclasses.dataclass class node_typedef(node): type:str="typedef" # 函数定义节点 @dataclasses.dataclass class node_func_def(node): type:str="func_def" # switch节点 @dataclasses.dataclass class node_switch(node): type:str="switch" # case节点 @dataclasses.dataclass class node_case(node): type:str="case" # default @dataclasses.dataclass class node_default(node): type:str="default" # break节点 @dataclasses.dataclass class node_break(node): type:str="break" # return节点 @dataclasses.dataclass class node_return(node): type:str="return" # 函数调用节点 @dataclasses.dataclass class node_call(node): type:str="call" # 变量操作节点 @dataclasses.dataclass class node_opt(node): type:str="opt_var" # 符号节点 @dataclasses.dataclass class node_symbol(node): type:str="symbol" # string节点 @dataclasses.dataclass class node_string(node): type:str="string" # 找到闭合的括号 def find_close(token_list:list[lex_token],token:tuple[int,int]): if token_list[0].token!=token[0]: return 0 num=0 for index,item in enumerate(token_list): if(item.token==token[0]): num+=1 elif(item.token==token[1]): num-=1 if(num==0): return index raise Exception(f"没有找到闭合的符号 {token[1]}") # 找到一个完整的语句 def find_sentence(token_list:list[lex_token],sep:list[int]=[lex_c.TOKEN(";"),lex_c.TOKEN(":")]): bracket_flag=False index=0 while index0): bracket_flag=True index+=bracket_index elif(token_list[index].token==lex_c.TOKEN("{")): bracket_index=find_close(token_list[index:],(lex_c.TOKEN("{"),lex_c.TOKEN("}"))) if(bracket_index>0): index+=bracket_index if(bracket_flag==True): return token_list[:index+1] elif(token_list[index].token in sep): return token_list[:index+1] index+=1 raise Exception(f"没有找到完整的语句") def dist_node_type_struct(token_list:list[lex_token]): if(token_list[0].token==lex_c.TOKEN_STRUCT): if(token_list[1].token==lex_c.TOKEN_SYMBOL): if(len(token_list)==2): return node_struct_decl(name=token_list[1].buff.decode("utf-8"),token_list=token_list) elif(token_list[2].token==lex_c.TOKEN("{")): if not token_list[-1].token==lex_c.TOKEN("}"): raise Exception("没有出现预期的符号 '}'") v_list:list[node_variable_def]=[] token_list_local=token_list[3:-1] while len(token_list_local)>0: sentence=find_sentence(token_list_local) v_list.append(dist_node_type(token_list=sentence)) token_list_local=token_list_local[len(sentence):] return node_struct_def(name=token_list[1].buff.decode("utf-8"),token_list=token_list,child=v_list) raise Exception(f"语法错误 {token_list[0]}") def dist_node_type_union(token_list:list[lex_token]): if(token_list[0].token==lex_c.TOKEN_UNION): if(token_list[1].token==lex_c.TOKEN_SYMBOL): if(len(token_list)==2): return node_union_decl(name=token_list[1].buff.decode("utf-8"),token_list=token_list) elif(token_list[2].token==lex_c.TOKEN("{")): if not token_list[-1].token==lex_c.TOKEN("}"): raise Exception("没有出现预期的符号 '}'") v_list:list[node_variable_def]=[] token_list_local=token_list[3:-1] while len(token_list_local)>0: sentence=find_sentence(token_list_local) v_list.append(dist_node_type(token_list=sentence)) token_list_local=token_list_local[len(sentence):] return node_union_def(name=token_list[1].buff.decode("utf-8"),token_list=token_list,child=v_list) raise Exception(f"语法错误 {token_list[0]}") def dist_node_type_enum(token_list:list[lex_token]): if(token_list[0].token==lex_c.TOKEN_ENUM): if(token_list[1].token==lex_c.TOKEN_SYMBOL): if(len(token_list)==2): return node_enum_decl(name=token_list[1].buff.decode("utf-8"),token_list=token_list) elif(token_list[2].token==lex_c.TOKEN("{")): if not token_list[-1].token==lex_c.TOKEN("}"): raise Exception("没有出现预期的符号 '}'") # token_list_local=token_list[3:-1] return node_enum_def(name=token_list[1].buff.decode("utf-8"),token_list=token_list,child=[]) raise Exception(f"语法错误 {token_list[0]}") def dist_node_type_typedef(token_list:list[lex_token]): if(token_list[0].token==lex_c.TOKEN_TYPEDEF): attr=[] token_list_local=token_list if(token_list[-1].token!=lex_c.TOKEN_SYMBOL): raise Exception(f"没有定义新类型 {token_list[-1]}") name=token_list[-1].buff.decode("utf-8") token_list=token_list[1:] while token_list[0].token in [lex_c.TOKEN_UNSIGNED,lex_c.TOKEN_CONST]: attr.append(token_list[0].name) token_list=token_list[1:] if(token_list[0].token==lex_c.TOKEN_STRUCT or token_list[0].token==lex_c.TOKEN_UNION): attr.append(token_list[0].name) if(token_list[1].token==lex_c.TOKEN_SYMBOL): node_r=None attr.append(token_list[1].buff.decode("utf-8")) if(token_list[2].token==lex_c.TOKEN("{")): node_r=dist_node_type(token_list=token_list[1:-1]) elif(token_list[2].token==lex_c.TOKEN("*")): attr.append(token_list[2].name) return node_typedef(name=name,token_list=token_list_local,child=node_r) if(token_list[0].token==lex_c.TOKEN_SYMBOL): # 使用typedef 定义过的自定义类型 attr.append(token_list[0].buff.decode("utf-8")) token_list=token_list[1:] else: # c语言预设类型 while(token_list[0].token in [lex_c.TOKEN_INT,lex_c.TOKEN_CHAR,lex_c.TOKEN_SHORT,lex_c.TOKEN_LONG,lex_c.TOKEN_FLOAT, lex_c.TOKEN_DOUBLE,lex_c.TOKEN_VOID,lex_c.TOKEN("*")]): attr.append(token_list[0].name) token_list=token_list[1:] if(len(token_list)>1): raise Exception(f"意外的token {token_list[0]}") return node_typedef(name=name,token_list=token_list_local,child=[]) raise Exception(f"语法错误 {token_list[0]}") # 找到子节点 def find_child(token_list:list[lex_token],seq:list[int]=[lex_c.TOKEN(";"),lex_c.TOKEN(":")]): child=[] for i in range(len(token_list)): if(token_list[i].token==lex_c.TOKEN("{")): token_list_local=token_list[i+1:-1] break while len(token_list_local)>0: sentence=find_sentence(token_list_local,seq) node_d=dist_node_type(sentence) child.append(node_d) token_list_local=token_list_local[len(sentence):] return child def dist_node_type_funcdef(token_list:list[lex_token]): for i in range(len(token_list)): if(token_list[i].token==lex_c.TOKEN_SYMBOL): name=token_list[i].buff.decode("utf-8") break return node_func_def(name=[name],token_list=token_list,child=find_child(token_list)) def dist_node_type_funcdecl(token_list:list[lex_token]): for i in range(len(token_list)): if(token_list[i].token==lex_c.TOKEN_SYMBOL): name=token_list[i].buff.decode("utf-8") return node_func_decl(name=[name],token_list=token_list,child=[]) raise Exception(f"函数声明格式错误 {token_list[0]}") # 第一个token是symbol的处理 def dist_node_type_symbol(token_list:list[lex_token]): # 变量赋值或函数调用 if(token_list[1].token == lex_c.TOKEN("(")): child=find_child(token_list=token_list[2:-1]) return node_call("call",token_list=token_list,child=child) elif(token_list[1].token in [ lex_c.TOKEN("="),lex_c.TOKEN_ASSIG_ADD,lex_c.TOKEN_ASSIG_DIV,lex_c.TOKEN_ASSIG_LSH, lex_c.TOKEN_ASSIG_MUL,lex_c.TOKEN_ASSIG_RSH,lex_c.TOKEN_ASSIG_SUB]): name=token_list[1].name child=[node_symbol(name=token_list[0].buff.decode("utf-8"),token_list=token_list[:1]), dist_node_type(token_list=token_list[2:])] return node_opt(name=name,token_list=token_list,child=child) else: # 没有赋值属性的操作 name=token_list[1].name return node_opt(name=name,token_list=token_list,child=[]) # 判断一个语句的类型 def dist_node_type(token_list:list[lex_token]): if(token_list[0].token==lex_c.TOKEN_EXTERN): token_list=token_list[1:] if(token_list[-1].token==lex_c.TOKEN(";")): token_list=token_list[:-1] if(token_list[0].token==lex_c.TOKEN_STRUCT): return dist_node_type_struct(token_list=token_list) if(token_list[0].token==lex_c.TOKEN_UNION): return dist_node_type_union(token_list=token_list) if(token_list[0].token==lex_c.TOKEN_ENUM): return dist_node_type_enum(token_list=token_list) if(token_list[0].token==lex_c.TOKEN_TYPEDEF): return dist_node_type_typedef(token_list=token_list) if(token_list[0].token==lex_c.TOKEN_SWITCH): child=find_child(token_list) return node_switch(name="switch",token_list=token_list,child=child) if(token_list[0].token==lex_c.TOKEN_CASE): return node_case(name="case",token_list=token_list,child=[]) if(token_list[0].token==lex_c.TOKEN_DEFAULT): return node_default(name="default",token_list=token_list,child=[]) if(token_list[0].token==lex_c.TOKEN_BREAK): return node_break(name="break",token_list=token_list,child=[]) if(token_list[0].token==lex_c.TOKEN_RETURN): return node_return(name="return",token_list=token_list,child=[]) if(token_list[0].token==lex_c.TOKEN_STRING): return node_string(name="string",token_list=token_list,child=[]) if(token_list[-1].token==lex_c.TOKEN(")")): # 函数声明 return dist_node_type_funcdecl(token_list) elif(token_list[-1].token==lex_c.TOKEN("}")): # 函数定义 return dist_node_type_funcdef(token_list=token_list) elif(token_list[0].token==lex_c.TOKEN_SYMBOL): # 变量赋值或函数调用 return dist_node_type_symbol(token_list=token_list) else: # 变量定义 for i in range(len(token_list)): if(token_list[i].token==lex_c.TOKEN_SYMBOL): name=token_list[i].buff.decode("utf-8") return node_variable_def(name=[name],token_list=token_list,child=[]) raise Exception(f"变量定义格式错误 {token_list[0]}") def print_node(n:node,deep:int): s="|"*deep print(f"{s} {n.type} {n.name}") # n.complite() if (not n.child is None) and len(n.child)>0: for item in n.child: print_node(item,deep+1) if __name__ == "__main__": file_name="main.c" with open(file_name,mode='rb') as f: token_list=lex(f.read()) file=node_file(name=file_name,token_list=token_list) while len(token_list)>0: sentence=find_sentence(token_list) node_d=dist_node_type(sentence) file.child.append(node_d) # print('找到一个语句:') # for item in sentence: # print(f"\t{item}") token_list=token_list[len(sentence):] print_node(file,0)