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

Lark解析器解析多行语句报UnexpectedCharacters错误

问题原因

报错和多行输入本身无关,核心是你写的Lark语法存在循环引用歧义,附带几处语法定义不严谨的问题:

  • expr规则最后一个分支匹配rest,但rest的第一个分支又反向匹配expr,两个规则形成无限递归的等价关系,解析器处理完第一条语句的分号后,无法明确下一个起始token的归约路径,就会抛出字符不匹配的错误。单行输入能解析成功属于路径巧合,不是语法本身没有问题。
  • 集合差运算的规则别名拼写错误:differnce应为difference
  • 集合字面量content规则存在冗余的嵌套可选括号,定义不严谨
  • 运算规则没有做原子项隔离,后续扩展运算优先级时会出现归约冲突
修复方案

删掉存在循环引用的rest层,新增独立的原子表达式层atom作为最小匹配单元,只匹配集合字面量和变量名,不反向引用上层运算规则,让解析路径清晰无歧义。修复后的完整可运行代码如下:

from lark import Lark

class SetLanguageLarkParser():
    def __init__(self):
        self.setParser = Lark(r"""
            start: statement+ 

            statement : "DISP" expr ";" -> display
                      | name "=" expr ";" -> assign

            expr : expr "+" atom -> union
                 | expr "-" atom -> difference
                 | expr "*" atom -> cross
                 | expr "|" atom -> intersection
                 | atom

            atom : content
                 | name

            content : "{" [ (NUMBER|WORD) ("," (NUMBER|WORD))* ] "}"
            name : WORD

            %import common.WORD
            %import common.NUMBER
            %import common.WS
            %ignore WS
        """, start='start')

def main():
    data = """
            x = {0};
            S = {1,2,3};
            DISP S + x;
            """
    setLangP = SetLanguageLarkParser()
    print(setLangP.setParser.parse(data).pretty())

if __name__ == "__main__":
    main()
验证说明

修复后不管是单行单语句、多行多语句,还是带集合运算的DISP语句,都可以正常解析,不会再出现UnexpectedCharacters: No terminal matches 'S' in the current parser context报错。

内容的提问来源于stack exchange,提问作者Stephen Rodriguez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 13:24:20