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

Antlr4词法层面如何支持整数与小数?解析自定义语法报错原因

关于Antlr4语法解析整数与小数的问题解答

问题描述

编写了一套支持整数和小数常规数学运算的Antlr4语法,定义如下:

grammar Calculation;

calculation: expr EOF;

// Parser rules
expr: expr (ADD|SUB) expr
    | expr (MUL|DIV) expr
    | expr POWER expr
    | expr MODULAR expr
    | LEFT_BRACKET expr RIGHT_BRACKET
    | SQRT LEFT_BRACKET expr RIGHT_BRACKET
    | NUMBER
    ;

// Lexer rules
ADD: '+';
SUB: '-';
MUL: '*';
DIV: '/';
LEFT_BRACKET: '(';
RIGHT_BRACKET: ')';
INT : [0-9]+;
NUMBER: INT ('.' [0-9]+)?;
POWER: '^';
SQRT: 'sqrt';
MODULAR: '%';

WS : [ \t\r\n]+ -> skip ;

但解析表达式(1+1)时,抛出警告:line 1:1 mismatched input'1 'expecting {'(), NUMBER,'sqrt'}。在expr规则中添加|INT后,解析恢复正常。疑问两点:

  1. 出现该错误的原因是什么?
  2. Antlr4如何在词法层面正确同时支持整数和小数?

问题解答

1. 错误原因解析

Antlr4的词法分析器遵循两个核心规则:

  • 最长匹配原则:优先匹配长度最长的可能token
  • 先定义先匹配原则:当多个规则能匹配相同长度的输入时,优先匹配先定义的规则

你的语法中先定义了INT : [0-9]+;,再定义NUMBER: INT ('.' [0-9]+)?;。输入1时,词法分析器会优先匹配INT类型的token,但expr规则只接受NUMBER类型,导致解析器找不到对应规则,抛出不匹配错误。添加|INT后,expr规则可以匹配INT类型的token,因此解析恢复正常。

2. 词法层面支持整数与小数的正确方式

不需要单独定义INT规则,因为整数本质是小数的特例(无小数点及后续数字)。直接将整数和小数的匹配逻辑合并到NUMBER规则中即可,修改后的词法规则如下:

// 移除原有的INT规则
NUMBER: [0-9]+ ('.' [0-9]+)?;

这样修改后:

  • 输入整数(如123)会被匹配为NUMBER token
  • 输入小数(如123.45)也会被匹配为NUMBER token
  • 完全符合Antlr4的最长匹配原则,不会出现拆分匹配的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 11:00:02