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

Antlr4 mismatched input错误:'protected'未被识别为MODIFIER

问题描述

定义了如下ANTLR语法规则:

declareField : MODIFIER* typeVar nameType ASSIGN value ';';
nameType : NAME(('.')NAME)*;
typeVar : nameType | nameType'<'typeVar'>' | typeVar'['']';
value : PRIMITIVE_VALUE;

以及对应的词法令牌规则:

ASSIGN : '=';

NULL : 'null';
INT : [0-9]+;
FLOAT : [0-9]+.[0-9]+;
STRING : '"'[a-zA-Z_0-9.]*'"';
CHAR : '\''[a-zA-Z_0-9]'\'';
BOOLEAN : TRUE | FALSE;
TRUE : 'true';
FALSE : 'false';

PRIMITIVE_VALUE : INT | FLOAT | STRING | CHAR | BOOLEAN | NULL;

PUBLIC : 'public';
PRIVATE : 'private';
FINAL : 'final';
STATIC : 'static';
VOLATILE : 'volatile';
TRANSIENT : 'transient';
SYNCHRONIZED : 'synchronized';
NATIVE : 'native';
ABSTRACT : 'abstract';
PROTECTED : 'protected';

MODIFIER : PUBLIC | PRIVATE | FINAL | STATIC | VOLATILE | TRANSIENT | SYNCHRONIZED | NATIVE | ABSTRACT | PROTECTED;

NAME : [a-zA-Z_][a-zA-Z_0-9]*;
WS: [ \t\r\n]+ -> channel(HIDDEN);

预期该语法能正确解析输入语句:

protected static final int test = 10;

但实际触发错误:

line 1:0 mismatched input 'protected' expecting {MODIFIER, NAME}

尽管protected已被明确定义为MODIFIER规则的分支,需要排查匹配错误的原因并解决。

错误原因

核心问题是词法规则的优先级逻辑与语法规则的令牌期望不匹配:

  • ANTLR词法分析器遵循「先定义的规则优先级更高」原则,你先定义了PROTECTED、STATIC等具体修饰符关键字规则,后定义MODIFIER规则。因此输入的protected、static等字符串会被优先匹配为PROTECTED、STATIC等具体令牌,永远不会被识别为MODIFIER令牌。
  • 而语法规则declareField开头使用MODIFIER*,期望接收MODIFIER类型的令牌,但实际得到的是PROTECTED、STATIC等具体令牌,因此触发输入不匹配错误。
解决方案

提供两种可行修复方案,按需选择:

方案一:修改语法规则适配具体令牌

保留现有词法规则,将语法规则中的MODIFIER替换为所有具体修饰符关键字的组合:

declareField : (PUBLIC | PRIVATE | FINAL | STATIC | VOLATILE | TRANSIENT | SYNCHRONIZED | NATIVE | ABSTRACT | PROTECTED)* typeVar nameType ASSIGN value ';';
nameType : NAME(('.')NAME)*;
typeVar : nameType | nameType'<'typeVar'>' | typeVar'['']';
value : PRIMITIVE_VALUE;

修改后语法规则可直接接受所有具体修饰符令牌,输入能正常解析。

方案二:简化词法规则统一令牌类型

删除单独的PUBLIC、PROTECTED等关键字词法规则,直接在MODIFIER中定义所有修饰符字符串:

ASSIGN : '=';

NULL : 'null';
INT : [0-9]+;
FLOAT : [0-9]+'\.'[0-9]+; // 修复原规则中.未转义的问题
STRING : '"'[a-zA-Z_0-9.]*'"';
CHAR : '\''[a-zA-Z_0-9]'\'';
BOOLEAN : 'true' | 'false';

PRIMITIVE_VALUE : INT | FLOAT | STRING | CHAR | BOOLEAN | NULL;

MODIFIER : 'public' | 'private' | 'final' | 'static' | 'volatile' | 'transient' | 'synchronized' | 'native' | 'abstract' | 'protected';

NAME : [a-zA-Z_][a-zA-Z_0-9]*;
WS: [ \t\r\n]+ -> channel(HIDDEN);

语法规则保持原有的declareField : MODIFIER* typeVar nameType ASSIGN value ';';即可,此时词法器会将所有修饰符字符串匹配为MODIFIER令牌,与语法规则期望一致。

额外优化提示

原FLOAT规则中的.未转义,会匹配任意字符(正则中.是通配符),已在方案二中修复为[0-9]+'\.'[0-9]+,避免错误匹配非数字分隔符的字符串。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 09:30:51