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

如何在语句a=1+1中区分加号1与正号1?Antlr语法报错解决

区分ANTLR语法中的一元/二元运算符并解决解析报错

问题背景

你定义的ANTLR语法如下:

grammar Test; 

prog: (stat NEWLINE)* ; 
stat: ID '=' expr; 
expr: expr ('*'|'/') expr 
  | expr ('+'|'-') expr 
  | INT 
  | '(' expr ')' 
  ;
NEWLINE : [\r\n]+ ; 
ID : [a-z]+;
NT : ('+'|'-')?[0-9]+ ; 
WS : [ \t]* -> skip;

你希望在语句a=1+1中区分二元运算符+和表示正号的一元运算符+,但实际解析时出现报错:

error: extraneous input '+1' expecting NEWLINE

错误原因

  1. 词法与语法规则不匹配:语法中expr规则引用了INT,但词法里定义的是NT,导致数字无法被正确识别,这是触发报错的直接原因;
  2. 未区分运算符优先级:原始expr规则仅定义了二元运算符的左递归结构,没有为优先级更高的一元运算符单独设置分支,无法正确解析带一元符号的表达式。

修正方案

调整语法结构拆分表达式规则以区分优先级,同时修正词法规则的命名匹配:

grammar Test; 

prog: (stat NEWLINE)* ; 
stat: ID '=' expr; 

// 二元加减表达式,优先级低于乘除
expr: expr ('+'|'-') term 
    | term
    ;

// 二元乘除表达式,优先级低于一元运算
term: term ('*'|'/') unary_expr
    | unary_expr
    ;

// 处理一元运算符及基础表达式单元
unary_expr: ('+'|'-')? (INT | '(' expr ')' | ID)
          ;

NEWLINE : [\r\n]+ ; 
ID : [a-z]+;
// 修正词法规则命名,与语法中的引用一致
INT : ('+'|'-')?[0-9]+ ; 
WS : [ \t]* -> skip;

修正说明

  • 词法规则修正:将NT改为INT,确保语法规则中的引用与词法定义一致;
  • 表达式分层:通过expr(加减)、term(乘除)、unary_expr(一元运算+基础元素)三层规则,实现运算符优先级的自然区分:
    • unary_expr处理一元+/-以及数字、括号表达式、变量(新增ID支持,避免变量无法参与表达式的问题);
    • 二元运算符的规则基于高优先级的unary_expr/term构建,确保解析时不会将二元运算符误判为一元运算符;
  • 这样修改后,a=1+1会被正确解析为:stat → ID=a + = + expr(1 二元+ 1),而a=+1则会被解析为stat → ID=a + = + unary_expr(一元+ 1),完美区分两种+的用法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 01:47:38