Запуск парсера Antlr4 с грамматикой лексера приводит к ошибкам распознавания токенов

Я пытаюсь создать грамматику для синтаксического анализа запросов Solr (только умеренно актуально, и вам не нужно ничего знать о solr, чтобы ответить на вопрос - просто знаю больше, чем я, о antlr 4.7). Я основываю его на файле QueryParser.jj из solr 6. Я искал уже существующий, но, похоже, нет такого, который не устарел и не устарел.

Я застрял, потому что когда я пытаюсь запустить синтаксический анализатор, я получаю «ошибку распознавания токена».

Созданный мной лексер использует режимы лексера, что, как я понимаю, означает, что мне нужен отдельный файл грамматики лексера. Итак, у меня есть парсер и файл лексера.

Я свел это к простому примеру, чтобы показать, что я вижу. Может кто подскажет, что я делаю не так. Вот парсер (Junk.g4):

grammar Junk;

options {
  language = Java;
  tokenVocab=JLexer;
}

term : TERM '\r\n'; 

Я не могу использовать импорт из-за режимов лексера в файле лексера, который я пытаюсь создать (токены в режимах становятся "неопределенными", если я использую импорт). Вот почему я ссылаюсь на файл лексера с параметром 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» - это термин). Кроме того, если я запустил файл лексера с помощью 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. Я делаю это в пакетном файле, поэтому уверен, что делаю это каждый раз.

Я не понимаю, что делаю не так. Это способ, которым я бегаю? Мы ценим любые предложения.


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