使用词法分析器语法运行Antlr4解析器会导致令牌识别错误

时间:2017-12-06 00:31:03

标签: parsing antlr4

我正在尝试创建一个语法来解析Solr查询(只是稍微有点相关,你不需要知道关于solr的任何事情来回答这个问题 - 只知道我对antlr 4.7的了解)。我基于solr 6的QueryParser.jj文件。我找了一个现有的,但似乎没有一个不老和过时。

我被困了,因为当我尝试运行解析器时,我得到“令牌识别错误”。

我创建的词法分析器使用词法分析器模式,据我所知,这意味着我需要一个单独的词法分析器语法文件。所以,我有一个解析器和一个lexer文件。

我把它简化为一个简单的例子来表明我看到了。也许有人可以告诉我我做错了什么。这是解析器(Junk.g4):

grammar Junk;

options {
  language = Java;
  tokenVocab=JLexer;
}

term : TERM '\r\n'; 

我无法使用导入,因为我正在尝试创建的词法分析器文件中的词法分析器模式(如果我使用导入,模式中的标记将变为“未定义”)。这就是我使用tokenVocab参数引用lexer文件的原因(如github中的XML示例所示)。

这是词法分析器(JLexer.g4):

lexer grammar JLexer;

TERM : TERM_START_CHAR TERM_CHAR* ;

TERM_START_CHAR : [abc] ;  
TERM_CHAR : [efg] ; 
WS  : [ \t\n\r\u3000]+ -> skip;

如果我将词法分析器代码复制到解析器中,那么事情就会按预期工作(例如,“aeee”是一个术语)。此外,如果我使用grun运行lexer文件(将标记指定为目标),则字符串将作为TERM进行解析(如预期的那样)。

如果我运行解析器(“grun Junk term -tokens”),那么我得到:

line 1:0 token recognition error at: 'a'
line 1:1 token recognition error at: 'e'
line 1:2 token recognition error at: 'e'
line 1:3 token recognition error at: 'e'
[@0,4:5='\r\n',<'
'>,1:4]

我首先“编译”词法分析器,然后“编译”解析器,然后javac生成的java文件。我在一个批处理文件中这样做,所以我非常有信心每次都这样做。

我不明白我做错了什么。这是我跑步的方式吗?任何建议将不胜感激。

1 个答案:

答案 0 :(得分:2)

始终相信你的直觉! grun内部有一些约定:-)请参阅此处TestRig.java c。第125,150行。如果还增加了一些额外的CLI参数,本来会更好。

当词法分析器和语法分开编译时,语法名称 - 在你的情况下 - 将是(在TestRig之前)&#34; Junk&#34;这两个文件必须命名为&#34; JunkLexer.g4&#34;和&#34; JunkParser.g4&#34;。因此,解析器文件JunkParser.g4中的标题也应该被修改

parser grammar JunkParser;
options { tokenVocab=JunkLexer; }
... stuff

现在您可以运行测试

> antlr4 JunkLexer
> antlr4 JunkParser
> javac Junk*.java
> grun Junk term -tokens
aeee
^Z
[@0,0:3='aeee',<TERM>,1:0]
[@1,6:5='<EOF>',<EOF>,2:0]
>