如何在语句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
错误原因
- 词法与语法规则不匹配:语法中
expr规则引用了INT,但词法里定义的是NT,导致数字无法被正确识别,这是触发报错的直接原因; - 未区分运算符优先级:原始
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
相关产品推荐
相关产品推荐

