词法分析器无法识别保留字与数据类型的问题求助
词法分析器识别问题:保留字/数据类型被误判为标识符
我正在开发一款词法分析器,需要对外部文本文件中的代码进行分词,识别运算符、标识符、常量、保留字和数据类型。但目前遇到问题:保留字和数据类型被识别为标识符而非对应类型。我知道是因为程序优先匹配了标识符的正则表达式,但不知道如何调整才能同时正确识别标识符/变量与保留字、数据类型。附上代码如下:
import re tokens = [] sample_code = open("book.txt","r").read().split() for word in sample_code: if re.match("[a-zA-Z]+", word): tokens.append([word,'is an Identifier']) elif re.match("([1-9][0-9]*)|0", word): if word[len(word) - 1] == ';': tokens.append([word[:-1], "is Num Constant"]) tokens.append([';', 'is a Semi-colon']) else: tokens.append([word, "is a Num Constant"]) elif word in ['str', 'int', 'bool','float','char']: tokens.append([word, 'is a Datatype']) elif word in '><!*-/+%=': tokens.append([word, "is an Operator"]) elif word in ['if','for','break','elif','else','while','then','call','do', 'endwhile', 'return','void','static','case','throw','private', 'public']: tokens.append([word, 'is a Reserved Word']) print(tokens, ' ')
解决思路与修正代码
核心问题是匹配顺序错误:你的代码先匹配标识符的正则([a-zA-Z]+),而保留字、数据类型都符合这个规则,导致它们被优先判定为标识符。调整匹配顺序,将保留字、数据类型的判断放在最前面即可解决。
具体修改点:
- 把保留字、数据类型的判断移到标识符判断之前
- 使用集合存储保留字/数据类型,提升查找效率
- 用
re.fullmatch替代re.match,确保整个单词完全匹配规则(避免部分匹配的问题) - 优化带分号单词的处理逻辑,先拆分再判断类型
修正后的代码:
import re tokens = [] # 用集合存储,查找更快 reserved_words = {'if','for','break','elif','else','while','then','call','do', 'endwhile', 'return','void','static','case','throw','private', 'public'} data_types = {'str', 'int', 'bool','float','char'} # 用with语句管理文件,更安全 with open("book.txt","r") as f: sample_code = f.read().split() for word in sample_code: processed_word = word has_semicolon = False # 先处理末尾带分号的情况 if processed_word.endswith(';'): processed_word = processed_word[:-1] has_semicolon = True # 1. 优先匹配保留字 if processed_word in reserved_words: tokens.append([processed_word, 'is a Reserved Word']) # 2. 再匹配数据类型 elif processed_word in data_types: tokens.append([processed_word, 'is a Datatype']) # 3. 匹配数字常量 elif re.fullmatch(r"([1-9][0-9]*)|0", processed_word): tokens.append([processed_word, "is a Num Constant"]) # 4. 最后匹配标识符(此时已排除保留字和数据类型) elif re.fullmatch(r"[a-zA-Z]+", processed_word): tokens.append([processed_word, 'is an Identifier']) # 5. 匹配运算符 elif processed_word in '><!*-/+%=': tokens.append([processed_word, "is an Operator"]) # 单独添加分号token if has_semicolon: tokens.append([';', 'is a Semi-colon']) print(tokens)
内容的提问来源于stack exchange,提问作者Farrah Atef
相关产品推荐
相关产品推荐

