ANTLR4报错‘no viable alternative’:多单词被识别为单个Token求助
问题分析与解决方案
核心问题:空白字符未被正确跳过
报错里的stringname、intage是输入中string name、int age的空格未被跳过,直接合并成了单个Token导致的。根源是词法规则中WS的跳过动作语法错误:
WS : [ \t\r\n]+ -> skip;
这里的->是HTML转义字符,ANTLR4无法识别,必须替换为语法要求的->,否则空白字符不会被处理,直接和相邻标识符拼接。
修复步骤
1. 修正WS词法规则
将WS规则改为标准写法,让ANTLR正确跳过空格、换行等空白字符:
WS : [ \t\r\n]+ -> skip;
修正后string name会被拆分为TYPE(string)和ID(name)两个独立Token,符合variable规则的要求。
2. 补全语法规则的缺失分支
statement规则中没有包含array分支,导致输入里的string children[];无法匹配,需修改:statement : variable | array // 添加数组定义分支 | if | function | loop | functionCall | show ;- 删除
variable规则里无效的| ...占位符,保留实际的变量定义逻辑。
3. 适配函数中return语句的语法
当前statement和if规则不支持return语句,而输入的isMinor函数包含return false;这类代码,需补充:
- 在
statement中添加return分支:statement : variable | array | if | function | loop | functionCall | show | 'return' VAR_TYPE ';' // 新增return语句支持 ; - 简化
if和loop规则的嵌套语句,直接复用statement避免重复定义:if: 'if' (ID | VAR_TYPE) COMPARISON (ID | VAR_TYPE) ':' ( '\t' statement )* ('else if' (ID | VAR_TYPE) COMPARISON (ID | VAR_TYPE) ':' ( '\t' statement )* )* ('else' ':' ( '\t' statement )* )? ;
修复后关键规则示例
grammar Grammar; start: (statement ';')*; statement : variable | array | if | function | loop | functionCall | show | 'return' VAR_TYPE ';' ; variable : TYPE ID ('=' VAR_TYPE)? ; array : TYPE ID '[]' ('=' '[' VAR_TYPE (',' VAR_TYPE)* ']')? ; // 其余规则按原有逻辑保留,仅调整WS和补充上述分支 WS : [ \t\r\n]+ -> skip;
验证效果
修正后,输入中的变量定义、数组声明、函数内的return语句和if逻辑都能被正确解析,不会再出现Token合并的报错,语法树可以处理完整的输入内容。
内容的提问来源于stack exchange,提问作者Artem Bachynskyi
相关产品推荐
相关产品推荐

