如何使用lrparsing实现不区分大小写的Delphi简化语法解析?
解决lrparsing解析简化Delphi的两类问题
一、修复End.被错误识别为Identifier的问题
lrparsing的Token匹配遵循定义优先级,如果Identifier的正则先匹配了End,剩余的.会被孤立或错误合并。解决思路是优先匹配带点的关键字结尾:
- 单独定义
END_DOTToken,正则设为r'End\.',同时开启大小写不敏感 - 把
END_DOT和其他关键字的Token定义放在Identifier之前,确保优先匹配 - 调整Identifier的正则为
r'[A-Za-z_][A-Za-z0-9_]*',明确排除点号,避免错误匹配带点内容
二、修复关键字Unit无法识别的问题
报错“Unrecognised token 'U'”通常是大小写匹配规则或Token优先级问题,修复步骤:
- 全局开启大小写不敏感:初始化Parser或Lexer时设置
ignore_case=True,让所有Token匹配不区分大小写 - 显式定义关键字Token:将
Unit作为单独Token定义,或者用统一的关键字正则(如r'(Unit|End)'),确保覆盖大小写变体 - 调整Token顺序:把所有关键字Token放在Identifier之前定义,避免关键字被当作标识符解析
- 排除关键字的标识符匹配:在Identifier的Token定义中,通过
exclude_tokens参数排除已定义的关键字,防止冲突
示例修复代码
from lrparsing import Token, Parser, Ref # 全局配置大小写不敏感 lexer_config = {'ignore_case': True} # 先定义特殊关键字和普通关键字 END_DOT = Token(r'End\.', **lexer_config) UNIT = Token(r'Unit', **lexer_config) END = Token(r'End', **lexer_config) # 定义标识符,排除已定义的关键字 IDENTIFIER = Token( r'[A-Za-z_][A-Za-z0-9_]*', **lexer_config, exclude_tokens=[UNIT, END] ) # 构建语法规则 unit_declaration = UNIT + IDENTIFIER + ';' + Ref('code_block') + END_DOT code_block = ... # 补充你的代码块语法规则 # 初始化解析器 parser = Parser(unit_declaration, lexer_kwargs=lexer_config)
额外调试技巧
开启Token调试模式,打印识别到的所有Token,快速排查匹配顺序问题:
parser.debug = True
内容的提问来源于stack exchange,提问作者Adrian Maire
相关产品推荐
相关产品推荐

