我正在尝试创建一个语法来解析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文件。我在一个批处理文件中这样做,所以我非常有信心每次都这样做。
我不明白我做错了什么。这是我跑步的方式吗?任何建议将不胜感激。
答案 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]
>