ANTLR4中‘mismatched input’错误的原因排查
问题:ANTLR解析GURU语言时的令牌识别错误
问题描述
我是ANTLR新手,正在为GURU语言开发解析器。编写完语法后在测试工具中验证,出现大量令牌识别错误,反复修改语法仍无法解决。
Guru语法代码
grammar Guru; /* PARSER RULES */ expertSystem : definition initialization completion rules variables EOF; // Defenition definition : GOAL ':' expertiseVariable; // Initialization initialization : INITIAL ':' (output | assignment | input)+; // Completion completion : DO ':' (assignment | output)+; // Rules rules : (rule)+; rule : RULE ':' ruleName (auxiliaryElement)* (ready)* IF ':' premise THEN ':' conclusion (reason)* (usedVariables)*; ruleName : IDENTIFIER; auxiliaryElement : priority | cost | test | comment; priority : PRIORITY ':' RANGE; cost : COST ':' RANGE; test : TEST ':' testValue; testValue : 'S' | 'E' | 'P'; comment : COMMENT ':' text; ready : READY ':' (readyCommand)+; readyCommand : output | assignment; // TODO: LOGOPERATOR premise : andExpression; andExpression : orExpression ('AND' orExpression)*; orExpression : atomicExpression ('OR' atomicExpression)*; atomicExpression : '(' premise ')' | comparisonExpression; comparisonExpression : comparisonOperand COMOPERATOR comparisonOperand; comparisonOperand : expertiseVariable | value | (function '(' expertiseVariable ')'); conclusion : (assignment)+; reason : REASON ':' text; usedVariables : needs | changes; needs : NEEDS ':' '{' expertiseVariable (',' expertiseVariable)* '}'; changes : CHANGES ':' '{' expertiseVariable (',' expertiseVariable)* '}'; // Variables variables : (variable)+; variable : VAR ':' expertiseVariable (variableCommand)*; variableCommand : find | label | when | cfType | rigor | limit; find : FIND ':' (findCommand)+; findCommand : assignment | input; label : LABEL ':' text; when : WHEN ':' whenValue; whenValue : 'F' | 'L' | 'N'; cfType : CFTYPE ':' cfTypeValue cfTypeValue; cfTypeValue : 'M' | 'P'; rigor : RIGOR ':' rigorValue; rigorValue : 'M' | 'C' | 'A'; limit : LIMIT ':' NUMBER; // General rules output : OUTPUT ':' text; assignment : expertiseVariable '=' value; input : INPUT ':' expertiseVariable TYPE ':' TYPES WITH ':' text; expertiseVariable : IDENTIFIER; function : IDENTIFIER; value : STRING | NUMBER; text: STRING; /* LEXER RULES */ GOAL : 'GOAL'; INITIAL : 'INITIAL'; DO : 'DO'; RULE : 'RULE'; IF : 'IF'; THEN : 'THEN'; PRIORITY : 'PRIORITY'; COST: 'COST'; TEST: 'TEST'; COMMENT : 'COMMENT'; READY : 'READY'; REASON : 'REASON'; NEEDS : 'NEEDS'; CHANGES : 'CHANGES'; VAR : 'VAR'; FIND : 'FIND'; LABEL : 'LABEL'; WHEN : 'WHEN'; CFTYPE : 'CFTYPE'; RIGOR : 'RIGOR'; LIMIT : 'LIMIT'; OUTPUT : 'OUTPUT'; INPUT : 'INPUT'; TYPE : 'TYPE'; WITH : 'WITH'; IDENTIFIER : [a-zA-Z_][a-zA-Z0-9_]*; STRING : '"' ~["]* '"'; RANGE : [1-9] [0-9]? | '100'; NUMBER : '0' | [1-9][0-9]*; TYPES : 'NUM' | 'STRING' | 'REAL'; LOGOPERATOR : 'AND' | 'OR'; COMOPERATOR : '>' | '<' | '>=' | '<=' | '=='; WS : [ \t\r\n]+ -> skip;
测试文本
GOAL: RESH INITIAL: OUTPUT: "Some text" COMPLETION: DO: OUTPUT: "Some text" RULE: R1 IF: RESH < 20 THEN: RESH = 20 VAR: RESH
错误信息
1:4 token recognition error at: ':' 2:7 token recognition error at: ':' 3:10 token recognition error at: ':' 3:12 token recognition error at: '"' 3:22 token recognition error at: '"' 4:10 token recognition error at: ':' 5:6 token recognition error at: ':' 5:14 token recognition error at: ':' 5:16 token recognition error at: '"' 5:26 token recognition error at: '"' 6:4 token recognition error at: ':' 7:2 token recognition error at: ':' 7:9 token recognition error at: '<' 8:4 token recognition error at: ':' 9:3 token recognition error at: ':' 1:0 mismatched input 'GOAL' expecting 'GOAL'
问题原因与解决方法
1. HTML转义字符引发令牌识别失败
ANTLR语法文件和测试文本中使用了HTML转义字符(如"代表双引号、->代表箭头、<代表小于号),但ANTLR无法识别这些转义序列,必须使用原始字符:
- 语法中修改:
- 将
STRING : '"' ~["]* '"';改为STRING : '"' ~["]* '"'; - 将
WS : [ \t\r\n]+ -> skip;改为WS : [ \t\r\n]+ -> skip; - 将
COMOPERATOR : '>' | '<' | '>=' | '<=' | '==';改为COMOPERATOR : '>' | '<' | '>=' | '<=' | '==';
- 将
- 测试文本中修改:
- 将所有
"替换为",<替换为<
- 将所有
2. 测试文本与语法规则不匹配
语法中completion规则定义为DO ':' ...,但测试文本中写的是COMPLETION:,语法里未定义COMPLETION令牌,且规则要求DO:开头。需将测试文本中的COMPLETION:删除或调整为符合语法的结构,比如直接保留DO:块:
DO: OUTPUT: "Some text"
3. 潜在的令牌冲突问题
语法中定义了LOGOPERATOR : 'AND' | 'OR';,但在解析规则中直接使用了'AND'和'OR'字符串字面量,虽然当前不是主要错误,但可能引发令牌匹配冲突。建议统一使用LOGOPERATOR,或者删除LOGOPERATOR定义直接用字面量。
内容的提问来源于stack exchange,提问作者Андрей
相关产品推荐
相关产品推荐

