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

如何用ANTLR4解析‘Leg 1: Jun 25’?语法报错求助

ANTLR4解析失败问题解决

问题场景

刚入门ANTLR4,编写自定义语法解析输入文本Leg 1: Jun 25,语法规则如下:

fragment DIGIT
  : [0-9];
fragment MONTH
  : [A-Z][a-z][a-z];
DATE
  : MONTH ' ' DIGIT+;
LEG_NUMBER
  : DIGIT+;

leg
 : 'Leg ' LEG_NUMBER ': ' DATE;

解析时报错:

line 1:0 mismatched input 'Leg 1' expecting 'Leg '

问题原因

核心原因是词法规则的贪婪匹配特性:
你的MONTH规则定义为[A-Z][a-z][a-z],会匹配任何首字母大写、后两个字母小写的三字母单词——包括输入中的Leg。而DATE规则是MONTH ' ' DIGIT+,因此整个Leg 1会被词法分析器识别为一个DATE token,而非拆分为'Leg '和LEG_NUMBER。

语法规则leg期望以'Leg ' token开头,但实际输入的Leg 1被识别为DATE token,因此出现匹配错误。

解决方法

方法1:限制MONTH为实际月份缩写

将通用的MONTH规则替换为具体的月份缩写列表,避免匹配到非月份的三字母单词:

fragment DIGIT
  : [0-9];
// 仅匹配实际月份缩写
fragment MONTH
  : 'Jan' | 'Feb' | 'Mar' | 'Apr' | 'May' | 'Jun' 
  | 'Jul' | 'Aug' | 'Sep' | 'Oct' | 'Nov' | 'Dec';
DATE
  : MONTH ' ' DIGIT+;
LEG_NUMBER
  : DIGIT+;

leg
 : 'Leg ' LEG_NUMBER ': ' DATE;

方法2:添加空格忽略规则(更健壮)

额外定义WS规则跳过空格、制表符等空白字符,同时调整语法规则去掉字面量中的空格,让解析器自动处理任意数量的空白:

fragment DIGIT
  : [0-9];
fragment MONTH
  : 'Jan' | 'Feb' | 'Mar' | 'Apr' | 'May' | 'Jun' 
  | 'Jul' | 'Aug' | 'Sep' | 'Oct' | 'Nov' | 'Dec';
DATE
  : MONTH WS DIGIT+;
LEG_NUMBER
  : DIGIT+;
// 忽略所有空白字符
WS
  : [ \t\r\n]+ -> skip;

leg
 : 'Leg' LEG_NUMBER ':' DATE;

这样修改后,输入Leg 1: Jun 25就能被正确解析,Leg会被识别为字面量,1匹配LEG_NUMBER,Jun 25匹配DATE。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 23:57:21