Изпълнението на синтактичен анализатор Antlr4 с граматика на лексер получава грешки при разпознаване на токени

Опитвам се да създам граматика за анализиране на Solr заявки (само леко уместни и не е нужно да знаете нищо за solr, за да отговорите на въпроса - просто знаете повече от мен за antlr 4.7). Базирам го на файла QueryParser.jj от solr 6. Потърсих съществуващ, но изглежда няма такъв, който да не е стар и неактуален.

Заседнал съм, защото когато се опитам да стартирам синтактичния анализатор, получавам „грешка при разпознаване на токен“.

Lexer, който създадох, използва режими на lexer, което, както разбирам, означава, че трябва да имам отделен граматичен файл на lexer. И така, имам анализатор и лексер файл.

Сведох го до прост пример, за да покажа, че виждам. Може би някой може да ми каже какво правя погрешно. Ето анализатора (Junk.g4):

grammar Junk;

options {
  language = Java;
  tokenVocab=JLexer;
}

term : TERM '\r\n'; 

Не мога да използвам импортиране поради режимите на лексер във файла на лексер, който се опитвам да създам (токените в режимите стават „недефинирани“, ако използвам импортиране). Ето защо препращам към lexer файла с параметъра tokenVocab (както е показано в XML примера в github).

Ето лексера (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" е термин). Освен това, ако стартирам lexer файла с grun (посочвайки токени като цел), тогава низът се анализира като 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 файлове. Правя това в пакетен файл, така че съм доста уверен, че правя това всеки път.

Не разбирам какво правя погрешно. Това ли е начинът, по който бягам grun? Всякакви предложения ще бъдат оценени.


person user2615860    schedule 06.12.2017    source източник


Отговори (1)


Винаги се доверявайте на интуицията си! Има някаква вътрешна конвенция за grun :-) Вижте тук TestRig.java c. редове 125, 150. Щеше да е много по-добре, ако бяха добавени и някои допълнителни CLI аргументи.

Когато лексерът и граматиката се компилират поотделно, името на граматиката - във вашия случай - ще бъде (доколкото TestRig отива) "Junk" и двата файла трябва да бъдат наречени "JunkLexer.g4" и "JunkParser.g4". Съответно заглавките във файла на анализатора 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]
>
person Dinesh    schedule 20.12.2017
comment
Това малко информация ми помогна да компилирам XML граматиката... благодаря... ;) - person deostroll; 24.05.2019