You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何消除Lark语法表达式歧义?不同版本解析异常问题

Lark语法跨版本解析歧义问题解决

我编写了一段自认为无歧义的Lark语法,但在不同Lark版本下解析结果异常,代码如下:

import lark

syntax = r"""
stmt: mov_stmt
    | special_stmt

mov_stmt: reg ASSIGN (reg | const)
special_stmt: ("RS" SPECIAL_ASSIGN const)

reg: REG
const: DEC_NUM

REG.2: /R[0-7]|RS/
DEC_NUM: /0|[1-9]\d*/i

ASSIGN: "="
SPECIAL_ASSIGN: "&="

WS: /[ \t]+/
%ignore WS
"""

parser = lark.Lark(syntax, start="stmt", parser="lalr")

print(parser.parse("R3 = 7"))   # 1. 正常
print(parser.parse("R3 = R7"))  # 2. 正常
print(parser.parse("RS &= 1"))  # 3. 在lark==1.1.9下失败;期望匹配special_stmt
print(parser.parse("RS = R7"))  # 4. 在lark-parser==0.12.0下失败;期望匹配mov_stmt

版本异常表现

  • 在lark-parser==0.12.0中,第4次调用解析RS = R7失败,报错信息:
lark.exceptions.UnexpectedToken: Unexpected token Token('ASSIGN', '=') at line 1, column 4.
Expected one of:
        * SPECIAL_ASSIGN
Previous tokens: [Token('RS', 'RS')]
  • 在lark==1.1.9中,第3次调用解析RS &= 1失败,报错信息:
lark.exceptions.UnexpectedToken: Unexpected token Token('SPECIAL_ASSIGN', '&=') at line 1, column 4.
Expected one of:
        * ASSIGN
Previous tokens: [Token('REG', 'RS')]

我认为该语法本应无歧义:=应始终对应mov_stmt,&=应始终对应special_stmt(仅适用于reg为RS的情况)。尝试为不同终结符设置优先级,但无效果,请问该如何消除这种歧义?


解决方案

问题根源是LALR解析器的前瞻决策冲突,以及不同版本中令牌匹配、优先级处理的差异。最直接且跨版本兼容的解决方式是拆分寄存器规则,明确区分普通寄存器和RS,避免解析器在看到RS时产生歧义。

修改后的语法代码:

import lark

syntax = r"""
stmt: mov_stmt
    | special_stmt

mov_stmt: (general_reg | RS) ASSIGN (general_reg | RS | const)
special_stmt: RS SPECIAL_ASSIGN const

general_reg: REG
const: DEC_NUM

REG.2: /R[0-7]/
DEC_NUM: /0|[1-9]\d*/i

ASSIGN: "="
SPECIAL_ASSIGN: "&="

WS: /[ \t]+/
%ignore WS
"""

parser = lark.Lark(syntax, start="stmt", parser="lalr")

print(parser.parse("R3 = 7"))   # 正常
print(parser.parse("R3 = R7"))  # 正常
print(parser.parse("RS &= 1"))  # 正常
print(parser.parse("RS = R7"))  # 正常

修改说明

  • 将原有的reg规则拆分为general_reg(匹配R0-R7)和单独的RS令牌,让解析器能明确区分两种寄存器类型。
  • 调整mov_stmt规则,允许RS作为赋值的源或目标;special_stmt规则则明确绑定RS与SPECIAL_ASSIGN,彻底消除了前瞻阶段的规则冲突。

这种方式无需依赖优先级设置,在不同Lark版本中都能稳定工作。


内容的提问来源于stack exchange,提问作者Jonathon Reinhart

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 15:46:18