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

ANTLR报错疑问:为何‘mismatched input’未包含!和^预期令牌?

ANTLR解析错误中预期令牌未包含'!'和'^'的疑问

语法定义

grammar Playground;

stmtList: (expr EOS)+;
expr:
IDENTIFIER ('!' | '^') IDENTIFIER
| expr ('*' | '/') expr
| expr ('+' | '-') expr
| INT
| IDENTIFIER;

MAKE: 'make';
INT: '0' | [1-9] [0-9]*;
IDENTIFIER: [a-zA-Z0-9]+;
EQUAL: '='; // Dummy token that can be recognised
EOS: '\r'? '\n';
WS: [ \t\n\r]+ -> skip;

测试输入

blah=blah

实际报错信息

line 1:4 mismatched input '=' expecting {'*', '/', '+', '-', EOS}

用户预期的报错形式:

line 1:4 mismatched input '=' expecting {'!', '^', '*', '/', '+', '-', EOS}

令牌生成结果

执行命令 grun Playground stmtList -tokens 后输出:

[@0,0:3='blah',<IDENTIFIER>,1:0]
[@1,4:4='=',<'='>,1:4]
[@2,5:8='blah',<IDENTIFIER>,1:5]
[@3,9:9='\n',<EOS>,1:9]
[@4,10:9='<EOF>',<EOF>,2:0]

ANTLR版本:4.11.1

疑问

为何ANTLR给出的预期令牌集中未包含expr规则第一个分支定义的'!'和'^'令牌?


原因分析

这核心是ANTLR解析器的状态问题:当它把第一个blah识别成独立的IDENTIFIER(匹配了expr规则的最后一个分支)后,就判定当前表达式已经完成。

此时解析器处于「表达式结束后」的状态,接下来只接受两种情况:要么是*/+这类二元操作符(用来扩展现有表达式,比如blah + 1这种嵌套结构),要么是EOS语句结束符。

而expr的第一个分支IDENTIFIER ('!' | '^') IDENTIFIER是个完整的表达式结构——它要求第一个IDENTIFIER后面必须立刻跟!或^,再衔接另一个IDENTIFIER,整个构成一个完整expr。但解析器已经把blah当成独立完成的expr,自然不会再考虑“在它后面加!或^拼成另一种expr”的情况,所以这两个符号不会出现在预期令牌列表里。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 14:50:33