使用Python开发词法分析器时构建Symbol Table遇到困难如何解决
词法分析器符号表实现方案
核心实现逻辑
符号表的核心需求是支持标识符的快速插入、检索,Python内置的dict结构完全可以满足需求,无需额外实现复杂的哈希表逻辑:
- 以标识符字符串作为字典的key,value存储标识符对应的属性(数据类型、作用域、出现行号等,可按需扩展)
- 插入操作直接对字典键赋值,检索操作直接读取字典键值即可,时间复杂度均为O(1)
修改后的完整代码
在原有代码基础上新增符号表功能,同时保留原有的token生成逻辑:
import re token_pair = [] # 初始化符号表,key为标识符名,value存储属性 symbol_table = {} # 临时存储当前声明的数据类型,用来关联变量和类型 current_datatype = None with open('SourceCodeForTesting.cpp', "r") as Source_Code: for line_num, line in enumerate(Source_Code, start=1): for word in line.split(): if word in ['str', 'int', 'bool', 'float']: token_pair.append([word , 'DATATYPE']) # 记录当前声明的数据类型,给后面的标识符用 current_datatype = word elif re.match(r"^[a-zA-Z_][a-zA-Z0-9_]*$", word): token_pair.append([word , 'IDENTIFIER']) # 标识符插入符号表逻辑 if word not in symbol_table: # 存入符号表,属性包括类型、首次出现行号 symbol_table[word] = { "datatype": current_datatype if current_datatype else "undefined", "first_line": line_num } # 每次遇到标识符都更新出现次数,可按需扩展 symbol_table[word]["count"] = symbol_table[word].get("count", 0) + 1 # 关联完类型后清空临时变量,避免后续非声明标识符误绑定 current_datatype = None elif word in '*-/+%=""': token_pair.append([word ,'OPERATOR']) current_datatype = None elif word == '(': token_pair.append([word ,'Left Parenthesis']) current_datatype = None elif word == ')': token_pair.append([word ,'Right Parenthesis']) current_datatype = None elif word == '{': token_pair.append([word ,'Left Curly Bracket']) current_datatype = None elif word == '}': token_pair.append([word ,'Right Curly Bracket']) current_datatype = None elif re.match(r"^[0-9]+;?$", word): if word.endswith(';'): token_pair.append([ word[:-1] , 'INTEGER']) token_pair.append([';' , 'END_STATEMENT']) current_datatype = None else: token_pair.append([word, 'INTEGER']) current_datatype = None else: token_pair.append([word , 'Others']) current_datatype = None print("生成的token对:") print(token_pair) print("\n符号表内容:") for ident, attr in symbol_table.items(): print(f"标识符:{ident}, 属性:{attr}") # 检索示例:检查标识符a是否存在 if 'a' in symbol_table: print(f"\n检索到标识符a的类型为:{symbol_table['a']['datatype']}")
功能使用说明
- 插入操作:识别到新标识符时自动存入
symbol_table,如果是声明场景(前面紧跟数据类型)会自动绑定对应的数据类型 - 检索操作:直接用
标识符 in symbol_table判断是否存在,用symbol_table[标识符]即可取出所有属性 - 可根据需求扩展符号表存储的属性,比如作用域标识、内存地址、变量值等
原有代码优化建议
- 现有
split()分词逻辑无法处理int a=10;这类无空格分隔的连续token,后续可以改用正则的findall方法切分所有合法token - 优化正则匹配规则,避免数字、标识符的误匹配,上面代码里已经调整了对应正则的写法
内容的提问来源于stack exchange,提问作者Abdul Daim Rizwan
相关产品推荐
相关产品推荐

