Tatsu Parser未切换至行内下一条规则的问题排查求助
排查Tatsu解析OSTW函数参数的问题
首先,你的核心问题是PEG语法的匹配顺序优先级导致解析器没有优先识别关键字参数(kwarg),反而把arg当成普通参数后,无法处理后续的=符号。以下是具体排查和修正步骤:
1. 检查参数列表的规则结构
你大概率是把参数列表定义成了仅允许普通参数,比如:
params ::= param (',' param)* param ::= expr
这种规则下,解析器遇到arg=时,会先把arg匹配成param(因为expr可以匹配标识符),剩下的=没有对应规则,自然报错预期)。
2. 调整规则匹配顺序(核心修复)
PEG语法是自上而下顺序匹配,所以必须让解析器先尝试匹配kwarg,再匹配普通参数。修正后的核心规则应该是:
call_expr ::= ID '(' args ')' ';' args ::= arg (',' arg)* | ε # 允许空参数列表 arg ::= kwarg | param # 优先匹配关键字参数,再匹配普通参数 kwarg ::= ID '=' expr param ::= expr
这里的关键是arg规则先写kwarg,再写param——当解析器看到ID=时,会优先触发kwarg规则,而不是把ID单独当成param。
3. 简化规则测试,逐步验证
先剥离复杂逻辑,用最小规则验证kwarg的解析:
start = call_expr ; call_expr = ID '(' kwarg ')' ';' ; kwarg = ID '=' ID ;
测试解析doSomething(arg=stuff);,如果成功,再逐步添加普通参数的规则,避免其他规则干扰排查。
4. 启用Tatsu调试追踪
在调用Tatsu解析时添加trace=True参数,查看解析过程的规则尝试路径:
parser.parse(code, trace=True)
通过调试日志可以明确看到,遇到=时解析器是否尝试了kwarg规则,还是直接走了param规则,定位具体的匹配冲突点。
示例完整修正后的EBNF
start = call_expr ; call_expr = ID '(' args ')' ';' ; args = arg (',' arg)* | ; # 空参数列表的情况 arg = kwarg | param ; kwarg = ID '=' expr ; param = expr ; # 根据OSTW语法扩展expr的定义,比如支持标识符、数字、字符串等 expr = ID | NUMBER | STRING ;
内容的提问来源于stack exchange,提问作者Mriswithe
相关产品推荐
相关产品推荐

