Antlr4-c3自定义语言实现报错:'EXECUTE'输入冗余问题排查
问题分析与解决
核心原因
错误提示extraneous input 'EXECUTE' expecting {, 'PROCEDURE', EXECUTE}看似矛盾,本质是**EXECUTE被Lexer识别为ID而非关键字**。Parser预期接收EXECUTE关键字token,但实际拿到的是ID类型token,因此触发不匹配错误。
修复方案
1. 确保Lexer中关键字规则优先于ID规则
Antlr Lexer会按规则定义顺序匹配同优先级token,关键字必须放在ID规则之前,避免被ID规则抢先匹配:
// 正确的Lexer规则顺序 EXECUTE: 'EXECUTE'; PROCEDURE: 'PROCEDURE'; // ID规则必须在所有关键字之后 ID: [a-zA-Z_][a-zA-Z0-9_]*;
2. 排查大小写匹配问题
如果你的语言允许大小写混用,但Lexer规则仅匹配大写的'EXECUTE',输入小写/混合大小写会被识别为ID。需开启大小写不敏感模式:
lexer grammar CustomLangLexer; options { caseInsensitive = true; } EXECUTE: 'EXECUTE'; PROCEDURE: 'PROCEDURE'; ID: [a-zA-Z_][a-zA-Z0-9_]*;
3. 验证Parser规则的正确性
确保Parser规则中正确引用EXECUTE关键字token,而非错误使用ID:
parser grammar CustomLangParser; options { tokenVocab = CustomLangLexer; } program: statement* EOF; statement: procedure_stmt | execute_stmt; // 正确使用PROCEDURE关键字 procedure_stmt: PROCEDURE ID '{' '}'; // 正确使用EXECUTE关键字 execute_stmt: EXECUTE ID;
4. 调试确认Token类型
通过打印Token流验证EXECUTE的识别类型,定位问题根源:
// Java调试代码示例 Lexer lexer = new CustomLangLexer(CharStreams.fromString("EXECUTE file")); CommonTokenStream tokens = new CommonTokenStream(lexer); tokens.fill(); for (Token token : tokens.getTokens()) { System.out.printf("Token类型: %s, 内容: '%s'%n", lexer.getVocabulary().getSymbolicName(token.getType()), token.getText()); }
如果输出中EXECUTE的类型是ID而非EXECUTE,说明Lexer规则仍存在问题,需重新检查。
5. 排查隐藏字符或规则冲突
确认输入的EXECUTE无额外空格、制表符等隐藏字符;同时检查Lexer中是否存在其他高优先级规则(如匹配单个字母的规则)会截断关键字匹配,需调整规则优先级。
内容的提问来源于stack exchange,提问作者rnatong1
相关产品推荐
相关产品推荐

