Files
parser_c/node_run.py
2024-12-06 19:33:26 +08:00

321 lines
12 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from copy import deepcopy
from cpu import cpu
from io import StringIO as string
class variable_type(object):
def __init__(self,attr:list[str],size:int,limit:tuple[int,int]=None):
# 对于函数 attr就是返回值类型 attr中包含 '()' 则表示函数
self.attr=attr
self.size=size
self.pack=4 # 默认4字节对齐
self.member:list[tuple[variable_type,str]]=[]
if not (limit is None):
self.min=limit[0]
self.max=limit[1]
if(self.min>self.max):
raise Exception(f"{self.attr} 最小值大于最大值 {limit}")
self.enum_types={}
# 对于函数 member就是形式参数
def add_member(self,member,name:str):
if(isinstance(member,(variable_type))):
self.member.append((member,name))
else:
raise Exception(f"参数类型不对 {type(member)}")
def add_enum_item(self,key:str,index:int):
if (not key in self.enum_types.keys()) and (not index in self.enum_types.values()):
self.enum_types[key]=index
return
print(self.enum_types.keys(),self.enum_types.values())
raise Exception(f"枚举类型键或值已存在 {key} {index}")
def get_enum_value(self,key:str):
return self.enum_types.get(key,None)
def eq(self,attr:list[str]):
attr.sort()
self.attr.sort()
if(len(self.attr) != len(attr)):
return False
for item1,item2 in zip(self.attr,attr):
if(item1 != item2):
return False
return True
def get_size(self):
if("struct" in self.attr):
size=0
for item in self.member:
item_size=((item[0].get_size()+(self.pack-1))//self.pack)*self.pack
size+=item_size
return size
elif("union" in self.attr):
size=0
for item in self.member:
item_size=item[0].get_size()
if(size<item_size):
size=item_size
return size
elif("enum" in self.attr):
return 4
else:
return self.size
class variable(object):
def __init__(self,name:str,attr:variable_type,value:int):
self.name=name
self.value_=value # 这个值是变量在内存中的首地址
self.attr=attr
def set_value(self,value):
if("const" in self.attr):
raise Exception(f"变量 {self.name} 不可写")
self.value_=value
def size(self):
return self.attr.get_size()
def value(self):
return self.value_,self.attr.get_size()
def member_value(self,member_stack:list[str]=[]):
off=0
deep=len(member_stack)
member=self.attr.member
index=0
member_index=0
member_len=len(member)
while index < deep:
while(member_index < member_len):
if(member[member_index][1]!=member_stack[index]):
off+=member[member_index][0].get_size()
member_index+=1
else:
index+=1
if(index==deep):
return self.value_+off,member[member_index][0].get_size()
member=member[member_index][0].member
member_index=0
member_len=len(member)
raise Exception(f"{self.name} 中不存在指定成员 {member_stack}")
return self.value()
class variable_alias(object):
def __init__(self,alias:str,attr:variable_type):
self.attr=attr
self.alias=alias
class run(object):
def __init__(self):
self.variable_type_list:list[variable_type]=[
variable_type(["char"],1,(-128,127)),
variable_type(["short"],2,(-32768,32767)),
variable_type(["int"],4,(-2147483648,2147483647)),
variable_type(["long"],4,(-2147483648,2147483647)),
variable_type(["long","long"],8,(-9223372036854775808,9223372036854775807)),
variable_type(["float"],4),
variable_type(["double"],8),
variable_type(["unsigned","char"],1,(0,0xff)),
variable_type(["unsigned","short"],2,(0,0xffff)),
variable_type(["unsigned","int"],4,(0,0xffffffff)),
variable_type(["unsigned","long"],4,(0,0xffffffff)),
variable_type(["unsigned","long","long"],8,(0,0xffffffff_ffffffff)),
]
variable_list_len=len(self.variable_type_list)
for i in range(variable_list_len):
item=deepcopy(self.variable_type_list[i])
item2=deepcopy(self.variable_type_list[i])
item3=deepcopy(self.variable_type_list[i])
item.attr.insert(0,"static")
self.variable_type_list.append(item)
item2.attr.insert(0,"const")
self.variable_type_list.append(item2)
item3.attr.insert(0,"static")
item3.attr.insert(1,"const")
self.variable_type_list.append(item3)
self.variable_type_alias:list[variable_alias]=[]
self.unname_struct_index=0
self.unname_union_index=0
self.unname_enum_index=0
self.cpu=cpu(0x1000_0000,1*1024*1024,0x2000_0000,1*1024*1024)
self.stack:list[variable]=[]
def variable_type_check(self,attr:list[str]):
'''
校验变量类型
attr:变量属性
如果该变量类型已存在 则返回True 否则返回False
'''
for item in self.variable_type_list:
if(item.eq(attr)):
return True
return False
def enum_type_check(self,key):
'''
校验枚举类型
key:枚举的名称
如果枚举名称已存在 则返回True 否则返回False
'''
for item in self.variable_type_list:
if("enum" in item.attr):
if item.get_enum_value(key):
return True
return False
def get_variable_type(self,attr:list[str]):
'''
根据变量属性列表返回变量类
attr:属性列表
'''
if(len(attr)==1):
for item in self.variable_type_alias:
if(item.alias==attr[0]):
return item.attr
for item in self.variable_type_list:
if(item.eq(attr)):
return item
raise Exception(f"变量类型不存在 {attr}")
def add_struct_type(self,pack:int,type_name:str,member:list[tuple[variable_type,str]]):
'''
添加一个结构体类型
pack:按pack字节对齐
type_name:类型名如果为None则生成匿名结构体类型
member:成员类型和成员名称
'''
if(type_name is None):
type_name=f"unname_struct{self.unname_struct_index}"
self.unname_struct_index+=1
attr=["struct",type_name]
if(self.variable_type_check(attr)):
raise Exception(f"类型已存在 {attr}")
vt=variable_type(attr,0,None)
vt.pack=pack
for item in member:
if("static" in item[0].attr):
raise Exception(f"结构体成员不能包含 static 属性 {item[0].attr}")
vt.add_member(item[0],item[1])
self.variable_type_list.append(vt)
def add_union_type(self,type_name:str,member:list[tuple[variable_type,str]]):
'''
添加一个联合体类型
pack:按pack字节对齐
type_name:类型名如果为None则生成匿名联合体类型
member:成员类型和成员名称
'''
if(type_name is None):
type_name=f"unname_union{self.unname_union_index}"
self.unname_union_index+=1
attr=["union",type_name]
if(self.variable_type_check(attr)):
raise Exception(f"类型已存在 {attr}")
vt=variable_type(attr,0,None)
for item in member:
if("static" in item[0].attr):
raise Exception(f"结构体成员不能包含 static 属性 {item[0].attr}")
vt.add_member(item[0],item[1])
self.variable_type_list.append(vt)
def add_enum_type(self,type_name:str,member:list[tuple[str,int]]):
'''
添加一个枚举类型
type_name:类型名如果为None则生成匿名结构体类型
member:枚举名称和枚举值
'''
if(type_name is None):
type_name=f"unname_enum{self.unname_union_index}"
self.unname_enum_index+=1
attr=["enum",type_name]
if(self.variable_type_check(attr)):
raise Exception(f"类型已存在 {attr}")
vt=variable_type(attr,4,None)
for item in member:
if(self.enum_type_check(item[0])):
raise Exception(f"枚举键已存在 {member}")
vt.add_enum_item(item[0],item[1])
self.variable_type_list.append(vt)
def add_type_alias(self,attr:list[str],new_name:str):
'''
添加一个类型别名
attr:类型的属性列表,
member:成员类型和成员名称
'''
if(len(attr)==1):
for item in self.variable_type_alias:
if(item.alias==attr[0]):
self.variable_type_alias.append(variable_alias(new_name,item.attr))
return
for item in self.variable_type_list:
if(item.eq(attr)):
self.variable_type_alias.append(variable_alias(new_name,item))
def add_variable(self,attr:list[str],name:str,value=None):
'''
添加一个变量
attr:变量类型的属性列表
name:变量名称
value:变量值 为None时不设置初值 这个参数暂时没有使用
'''
for item in self.stack:
if(item.name==name):
raise Exception(f"符号名称已存在 {name}")
if(len(attr)==1):
for item in self.variable_type_alias:
if(item.alias==attr[0]):
addr=self.cpu.create_var(item.attr.get_size())
self.stack.append(variable(name,item.attr,addr))
return
for item in self.variable_type_list:
if(item.eq(attr)):
addr=self.cpu.create_var(item.get_size())
self.stack.append(variable(name,item,addr))
def set_variable(self,name:str,value,member_stack:list[str]=[]):
'''
设置变量值
name:要设置的变量名称
value:变量值
member_stack:变量的成员
'''
for item in self.stack:
if(item.name==name):
addr,size=item.member_value(member_stack)
self.cpu.set_value(addr,size,value)
return
raise Exception(f"符号名称不存在 {name}")
def get_variable(self,name:str,member_stack:list[str]=[]):
'''
获取变量的值
name:变量名
member_stack:变量成员,成员的成员
'''
for item in self.stack:
if(item.name==name):
addr,size=item.member_value(member_stack)
print(f"addr={addr},size={size}")
return self.cpu.get_value(addr,size)
def __str__(self) -> str:
ret=string()
ret.write("变量类型\n")
for item in self.variable_type_list:
ret.write(f"\t{item.attr}\n")
ret.write("变量别名\n")
for item in self.variable_type_alias:
ret.write(f"\t{item.attr.attr} eq {item.alias}\n")
ret.write("变量栈\n")
for item in self.stack:
addr,size=item.value()
ret.write(f"\t{item.attr.attr} {item.name}={hex(addr)},{size}\n")
ret_str=ret.getvalue()
ret.close()
return ret_str
if __name__ == "__main__":
f=run()
f.add_enum_type("enum1",[("ENUM0",0),("ENUM1",1)])
f.add_struct_type(4,"struct1",[
(f.get_variable_type(['int']),'a'),
(f.get_variable_type(['int']),'b'),
])
f.add_type_alias(['unsigned','char'],'uint8_t')
f.add_type_alias(['struct','struct1'],'struct1_def')
f.add_type_alias(['struct1_def'],'struct1_def_def')
f.add_variable(['unsigned','char'],'char_a',120)
f.add_variable(['uint8_t'],'char_b',100)
f.add_variable(['struct',"struct1"],'struct_a')
f.get_variable("struct_a")
f.get_variable("struct_a",['a'])
f.get_variable("struct_a",['b'])
print(f)