from prettytable import PrettyTable class Symbol: """ 符号基类 """ def __init__(self, name): """ 构造 :param name: 符号名 """ self.name = name class SymbolTable: """ 符号表 """ def __init__(self): """ 构造 """ self._table = list() def exist(self, name): """ 给定名字的符号是否存在 :param name: :return: True/False """ for s in self._table: if s.name == name: return True return False def query(self, name): """ 查询特定名字的符号 :param name: 名字 :return: 符号 """ for symbol in self._table: if symbol.name == name: return symbol return None def append(self, symbol): """ 填入符号 :param symbol: 符号 """ pass def num(self): """ 获取符号总数 :return: 符号总数 """ return len(self._table) def get(self, index): """ 根据索引来获取符号 :param index: 索引 :return: 符号 """ return self._table[index] class SymbolTablePool: """ 符号表池 """ def __init__(self): """ 构造 """ self.global_var_table = None self.local_var_tables = None self.fun_table = None def init(self): """ 初始化符号表池 """ self.global_var_table = GlobalVarTable() self.local_var_tables = list() self.fun_table = FunTable() # 添加 output 和 input 的支持 # self.local_var_tables.append( # LocalVarTable('input', self.global_var_table) # ) # self.local_var_tables.append( # LocalVarTable('output', self.global_var_table) # ) # self.query('output').append( # LocalVar('output_name', 'i32', 4, True) # ) # self.fun_table.append( # Fun('input', 'i32', self.query('input')) # ) # self.fun_table.append( # Fun('output', 'void', self.query('output')) # ) def change_fun_type(self, fun_name, type): """ 修改函数的返回类型 :param fun_name: 函数名 type: 返回类型 :return: bool """ return self.fun_table.chang_fun_type(fun_name=fun_name, type=type) def query(self, local_var_table_name): """ 查询局部变量表 :param local_var_table_name: 表名 :return: 局部变量表 """ for table in self.local_var_tables: if table.name == local_var_table_name: return table return None def append(self, local_var_table): """ 添加一张局部变量表 :param local_var_table: 局部变量表 """ self.local_var_tables.append(local_var_table) def debug(self): output = [] # Global Variable Table output.append("Global Variable Table:") table = PrettyTable() table.field_names = ["Name", "Type", "Width", "Offset"] for symbol in self.global_var_table._table: table.add_row([ getattr(symbol, "name", ""), getattr(symbol, "type", ""), getattr(symbol, "width", ""), getattr(symbol, "offset", "") ]) output.append(str(table)) # Function Table output.append("\nFunction Table:") fun_table = PrettyTable() fun_table.field_names = ["Function Name", "Return Type", "Local Var Table"] for fun in self.fun_table._table: local_table_name = getattr(fun, "table", None) local_table_name = local_table_name.name if local_table_name else "" fun_table.add_row([ fun.name, getattr(fun, "return_type", ""), local_table_name ]) output.append(str(fun_table)) # Local Variable Tables output.append("\nLocal Variable Tables:") for table_obj in self.local_var_tables: output.append(f"LocalVarTable: {table_obj.name}") local_table = PrettyTable() local_table.field_names = ["Name", "Type", "Width", "Offset", "Is Param"] for symbol in table_obj._table: local_table.add_row([ getattr(symbol, "name", ""), getattr(symbol, "type", ""), getattr(symbol, "width", ""), getattr(symbol, "offset", ""), getattr(symbol, "is_param", "") ]) output.append(str(local_table)) return "\n".join(output) class GlobalVarTable(SymbolTable): """ 全局变量表 """ def __init__(self): """ 构造 :param name: """ super().__init__() self.__width = 0 def append(self, symbol): """ 添加符号 :param symbol: 符号 """ self._table.append(symbol) self._table[-1].offset = self.__width self.__width += self._table[-1].width class GlobalVar(Symbol): """ 全局变量 """ def __init__(self, g_name, g_type, g_width): """ 全局变量 :param g_name: 名字 :param g_type: 类型 :param g_width: 长度 """ super().__init__(g_name) self.type = g_type self.width = g_width class LocalVarTable(SymbolTable): """ 局部变量表 """ def __init__(self, name, global_var_table): """ 构造 :param name: 表名 :param global_var_table 全局变量表 """ super().__init__() self.name = name self.outer = global_var_table self.__width = 0 def append(self, symbol): """ 填入新符号 :param symbol: """ self._table.append(symbol) self._table[-1].offset = self.__width self.__width += symbol.width def exist(self, name): """ 是否已经存在 :param name: 符号名 :return: True/False """ if self.outer.exist(name): return True else: for symbol in self._table: if symbol.name == name: return True return False def get_params_num(self): """ 获取参数个数 :return: 参数个数 """ num = 0 for symbol in self._table: if symbol.is_param: num += 1 return num def get_params(self): """ 获取参数列表 :return: 参数列表 """ params = list() for symbol in self._table: if symbol.is_param: params.append(symbol) return params class LocalVar(Symbol): """ 局部变量 """ def __init__(self, l_name, l_type, l_width, l_is_param): """ 构造 :param l_name: 名字 :param l_type: 类型 :param l_width: 占空间 :param l_is_param: 是否为参数 """ super().__init__(l_name) self.type = l_type self.width = l_width self.is_param = l_is_param class FunTable(SymbolTable): """ 函数表 """ def __init__(self): """ 构造 """ super().__init__() def append(self, symbol): """ 填入一个新的函数 :param symbol: 函数 """ self._table.append(symbol) def chang_fun_type(self, fun_name, type): for record in self._table: if record.name == fun_name: record.return_type = type return True return False class Fun(Symbol): """ 函数 """ def __init__(self, name, return_type, local_var_table): """ 构造 :param name: 函数名 :param return_type: 返回类型 :param local_var_table: 对应的局部变量表 """ super().__init__(name) self.param_types = list() self.return_type = return_type self.table = local_var_table