ANTLR 4.5 - 不匹配的输入' x'期待' x'

时间:2015-04-21 16:15:01

标签: antlr antlr4

我已经开始使用ANTLR,并注意到它的词法分析规则相当变幻无常。一个非常令人沮丧的例子如下:

grammar output;

test: FILEPATH NEWLINE TITLE ;

FILEPATH: ('A'..'Z'|'a'..'z'|'0'..'9'|':'|'\\'|'/'|' '|'-'|'_'|'.')+ ;
NEWLINE: '\r'? '\n' ;
TITLE: ('A'..'Z'|'a'..'z'|' ')+ ;

这个语法不匹配:

C:\ test.txt的
X

奇怪的是,如果我将TITLE更改为TITLE: 'x' ;,则此时仍然会失败,并显示错误消息“#34;输入不匹配' x'期待' x'"这非常令人困惑。更奇怪的是,如果我将TITLEtest的用法替换为FILEPATH,那么整个事情就会起作用(尽管FILEPATH会比我想匹配的更多,所以一般来说对我来说不是有效的解决方案。)

我非常困惑为什么ANTLR会发出如此极其奇怪的错误,然后突然出现这种情况时突然出现的问题。

3 个答案:

答案 0 :(得分:52)

这似乎是对ANTLR

的常见误解

ANTLR中的语言处理:

语言处理分为两个严格分开的阶段:

  • Lexing,即将文本分区为标记
  • 解析,即从令牌构建解析树

由于lexing必须先解析,因此有一个结果:词法分析器独立于解析器,解析器不能影响lexing

<强>乐星

在ANTLR中的Lexing工作原理如下:

  • 所有带有大写第一个字符的规则都是词法规则
  • 词法分析器从头开始,并尝试查找与当前输入最匹配的规则
  • 最佳匹配是匹配,其最大长度为,即将下一个输入字符附加到最大长度匹配所产生的令牌与任何词法规则不匹配
  • 令牌由匹配生成:
    • 如果一条规则最大长度匹配匹配,则相应的标记将被推送到标记流
    • 如果多个规则最大长度匹配匹配,则语法中第一个定义的令牌将被推送到令牌流

示例:语法有什么问题

你的语法有两条至关重要的规则:

FILEPATH: ('A'..'Z'|'a'..'z'|'0'..'9'|':'|'\\'|'/'|' '|'-'|'_'|'.')+ ;
TITLE: ('A'..'Z'|'a'..'z'|' ')+ ;

每个与TITLE匹配的匹配也将与FILEPATH匹配。并且在TITLE之前定义了FILEPATH:因此,您希望成为标题的每个标记都是FILEPATH。

有两个提示:

  • 保持你的词法分析规则不连续(没有令牌应该匹配另一个的超集)。
  • 如果您的代币故意匹配相同的字符串,则将它们按正确的顺序排列(在您的情况下,这就足够了)。
  • 如果你需要一个解析器驱动的词法分析器,你必须改为另一个解析器生成器:PEG-Parsers或GLR-Parsers会这样做(但当然这会产生其他问题)。

答案 1 :(得分:0)

我有同样的错误,但我无法想象可能会涉及到词法分析器的哪个规则。
我正在尝试解析Cobol的一些CDE文件-我认为这是特定于HP Nonstop的。

无论如何,我想解析的东西类似

* SCHEMA PRODUCED DATE - TIME : 1/29/2019 - 15:17:01
?SECTION MYREQUEST,NONSTOP
* Definition MYREQUEST created on 05/11/2016 at 11:05
  01 MYREQUEST. 
  ...

并且解析器失败

mismatched input '?SECTION foo' expecting '?'

我的语法是这样的

grammar CdeFile;

cdeFile : line+ ;
line : sectionLine ;
sectionLine : QUESTIONMARK SECTION sectionName '\r'? '\n' ;
sectionName : TEXTLIST ;

QUESTIONMARK : '?' ;
SECTION: S E C T I O N ;

TEXTLIST : TEXT (',' TEXT)* ;
TEXT : ~[,\n\r"]+ ;

WS : ( ' ' | '\t' | '\f' )+ -> skip;
LINE_COMMENT 
     : '*' {Column == 1}? '*'* ~('\n'|'\r')* '\r'? '\n' ->skip 
     ; 


// case insensitive chars
fragment A:('a'|'A');
fragment B:('b'|'B');
fragment C:('c'|'C');
fragment D:('d'|'D');
fragment E:('e'|'E');
fragment F:('f'|'F');
fragment G:('g'|'G');
fragment H:('h'|'H');
fragment I:('i'|'I');
fragment J:('j'|'J');
fragment K:('k'|'K');
fragment L:('l'|'L');
fragment M:('m'|'M');
fragment N:('n'|'N');
fragment O:('o'|'O');
fragment P:('p'|'P');
fragment Q:('q'|'Q');
fragment R:('r'|'R');
fragment S:('s'|'S');
fragment T:('t'|'T');
fragment U:('u'|'U');
fragment V:('v'|'V');
fragment W:('w'|'W');
fragment X:('x'|'X');
fragment Y:('y'|'Y');
fragment Z:('z'|'Z');

QUESTIONMARK值是同步的,所有内容都已重建-仍然是此奇怪的消息。

答案 2 :(得分:0)

这不是OP的直接问题,但是对于那些具有相同错误消息的人,您可以检查一下。


当我引入一个新关键字时,我得到了同样的Mismatched Input 'x' expecting 'x'模糊错误消息。对我来说,原因是我将新关键字放在了VARNAME词法分析器规则之后,该规则将其分配为变量名而不是新关键字。我通过将关键字放在VARNAME规则之前来解决此问题。