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

如何修复LALR(1) Lark DSL语法,解析无括号&&连接的多赋值表达式?

解决LALR(1) Lark语法中&&与赋值语句的解析冲突问题

问题根源

当前语法在解析(a == 2 && b == 3) ? (c = 12 && d = 13);时,错误尝试将其解析为(c = (12 && d) = 13),核心原因是表达式层级结构不符合需求:

  • 原规则中logical_and_expression仅接受equality_expression作为操作数,无法识别赋值表达式
  • 赋值表达式的右递归规则会强制将12 && d =13视为赋值右操作数,而12 && d并非合法的赋值左值,最终导致解析失败

修复方案

调整表达式层级,让赋值表达式可以作为逻辑与运算符的操作数,同时保持运算符优先级和语义的正确性。修改后的完整Lark语法如下:

?start: statement*

?statement: expression ";"

?expression : conditional_expression

?conditional_expression : logical_or_expression
                        | logical_or_expression "?" expression (":" expression)?

?logical_or_expression : logical_and_expression
                       | logical_or_expression "||" logical_and_expression

?logical_and_expression : assignment_expression
                        | logical_and_expression "&&" assignment_expression

?assignment_expression : equality_expression
                       | primary_expression assignment_op assignment_expression

?equality_expression : relational_expression
                     | equality_expression equals_op relational_expression
                     | equality_expression not_equals_op relational_expression

?relational_expression : additive_expression
                       | relational_expression less_than_op additive_expression
                       | relational_expression greater_than_op additive_expression
                       | relational_expression less_than_eq_op additive_expression
                       | relational_expression greater_than_eq_op additive_expression

?additive_expression : multiplicative_expression
                     | additive_expression add_op multiplicative_expression
                     | additive_expression sub_op multiplicative_expression

?multiplicative_expression : primary_expression
                           | multiplicative_expression mul_op primary_expression
                           | multiplicative_expression div_op primary_expression
                           | multiplicative_expression mod_op primary_expression

?primary_expression : variable
                    | variable "[" INT "]"    -> array_accessor
                    | ESCAPED_STRING
                    | NUMBER
                    | unary_op expression
                    | invoke_expression
                    | "(" expression ")"

invoke_expression : ID ("." ID)* "(" argument_list? ")"
argument_list : expression ("," expression)*

unary_op : "-" -> negate_op
         | "!" -> invert_op
assignment_op : "="
add_op : "+"
sub_op : "-"
mul_op : "*"
div_op : "/"
mod_op : "%"
equals_op : "=="
not_equals_op : "!="
greater_than_op : ">"
greater_than_eq_op : ">="
less_than_op : "<"
less_than_eq_op : "<="

ID : CNAME | CNAME "%%" CNAME

?variable : ID
    | ID "@" ID           -> namelist_id
    | ID "@" ID "@" ID    -> exptype_id
    | "$" ID              -> environment_id

%import common.WS
%import common.ESCAPED_STRING
%import common.CNAME
%import common.INT
%import common.NUMBER
%import common.CPP_COMMENT

%ignore WS
%ignore CPP_COMMENT

关键修改说明

  1. 调整逻辑与表达式的操作数类型:将logical_and_expression的基础规则从equality_expression改为assignment_expression,允许赋值表达式作为逻辑与的操作数,确保c=12 && d=13被解析为(c=12) && (d=13)。
  2. 重构表达式层级:将expression的顶层改为conditional_expression,确保三元条件表达式可以包含赋值和逻辑表达式;同时将assignment_expression的基础规则改为equality_expression,避免层级混乱。
  3. 保留原有语义:所有原合法示例(如带括号的逻辑与、三元条件语句)仍可正常解析,不会破坏现有功能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 18:46:11