我已经开始使用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'"这非常令人困惑。更奇怪的是,如果我将TITLE
中test
的用法替换为FILEPATH
,那么整个事情就会起作用(尽管FILEPATH
会比我想匹配的更多,所以一般来说对我来说不是有效的解决方案。)
我非常困惑为什么ANTLR会发出如此极其奇怪的错误,然后突然出现这种情况时突然出现的问题。
答案 0 :(得分:52)
这似乎是对ANTLR
:
ANTLR中的语言处理:
语言处理分为两个严格分开的阶段:
由于lexing必须先解析,因此有一个结果:词法分析器独立于解析器,解析器不能影响lexing 。
<强>乐星强>
在ANTLR中的Lexing工作原理如下:
示例:语法有什么问题
你的语法有两条至关重要的规则:
FILEPATH: ('A'..'Z'|'a'..'z'|'0'..'9'|':'|'\\'|'/'|' '|'-'|'_'|'.')+ ;
TITLE: ('A'..'Z'|'a'..'z'|' ')+ ;
每个与TITLE匹配的匹配也将与FILEPATH匹配。并且在TITLE之前定义了FILEPATH:因此,您希望成为标题的每个标记都是FILEPATH。
有两个提示:
答案 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
规则之前来解决此问题。