Files
parser_c/parser_c.py
2024-12-05 17:54:28 +08:00

387 lines
12 KiB
Python

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 index<len(token_list):
if(token_list[index].token==lex_c.TOKEN("(")):
bracket_index=find_close(token_list[index:],(lex_c.TOKEN("("),lex_c.TOKEN(")")))
if(bracket_index>0):
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)