Antlr4单个数字识别失败及括号优先级失效问题求助
Antlr4语法规则问题排查与修复
问题1:无法识别单个字符数字
原因
Lexer规则中,IDENTIFIER定义为(LETTER | DEC_DIGIT | '_')+,单个数字完全符合该规则的匹配条件。同时IDENTIFIER规则的位置在INTEGER_VALUE和DECIMAL_VALUE之前,Antlr4的Lexer会优先匹配更早出现的规则,导致单个数字被识别为IDENTIFIER,而非数字类型令牌。
修复方案
- 调整规则顺序:将数字相关规则(
BYTELENGTH_LITERAL、INTEGER_VALUE、DECIMAL_VALUE)移到IDENTIFIER之前,确保数字优先被匹配:
BYTELENGTH_LITERAL : DEC_DIGIT+ ('B' | 'K' | 'M' | 'G') ; INTEGER_VALUE : [-]*DEC_DIGIT+ ; DECIMAL_VALUE : DEC_DIGIT+ EXPONENT | DECIMAL_DIGITS EXPONENT? {isValidDecimal()}? ; IDENTIFIER : (LETTER | DEC_DIGIT | '_')+ ;
- 优化标识符规则(可选):修改
IDENTIFIER定义,要求必须包含至少一个字母或下划线,彻底避免纯数字被识别为标识符:
IDENTIFIER : (LETTER | '_') (LETTER | DEC_DIGIT | '_')* ;
问题2:普通单括号无法改变计算优先级
原因
- Lexer中未定义单个
(和)的规则,输入单个括号时会被匹配到ERROR_RECONGNIGION规则,无法生成有效令牌。 - Parser的
valueCalc规则仅支持双括号LEFT_BRACKET((()和拼写错误的RGIHT_BRACKET())),未处理单个括号的语法逻辑。
修复方案
- 添加单个括号Lexer规则:注意要放在双括号规则之后(Antlr4会优先匹配更长的令牌,避免双括号被拆分为单个括号),同时修正原规则的拼写错误:
LEFT_BRACKET : '((' ; RIGHT_BRACKET // 修正原拼写错误RGIHT_BRACKET : '))' ; LEFT_PAREN : '(' ; RIGHT_PAREN : ')' ; LEFT_BRACKET1 : '{{' ; RIGHT_BRACKET1 // 修正原拼写错误RGIHT_BRACKET1 : '}}' ;
- 修改Parser支持单个括号:更新
valueCalc规则,添加单个括号的语法分支:
valueCalc: LEFT_PAREN valueCalc RIGHT_PAREN | LEFT_BRACKET valueCalc RIGHT_BRACKET | LEFT_BRACKET1 valueCalc RIGHT_BRACKET1 | valueCalc ('*'|'/'|'%') valueCalc | valueCalc ('+'|'-') valueCalc | valueCalc ('<<'|'>>') valueCalc | values ;
内容的提问来源于stack exchange,提问作者hanhe
相关产品推荐
相关产品推荐

