antlr4 - как реализовать рекурсию

1

Я хочу проанализировать следующий ввод:

<name 1> WITH <name 2> WITH <name 3> WITH <name 4> ...

Я пробовал следующую грамматику:

WITH        : 'WITH'
            ;
NAME        : ('a'..'z' | 'A'..'Z' | '0'..'9' | '-' | '_')+
            ;
query       : NAME (WITH query)?
            ;

Но это, похоже, не работает. Как я могу реализовать рекурсию?

довожу до вашего сведения

Моя конечная цель - разобрать древовидную структуру следующим образом:

<name 1> WITH (<name 2> WITH <name 3> WITH <name 4>) WITH <name 5>

Это создает следующее дерево:

<name 1>
  <name 2>
    <name 3>
    <name 4>
  <name 5>

Но сначала начнем с первого выражения.

Мой код:

new TParser(new CommonTokenStream(new TLexer(new ANTLRInputStream( "hello WITH world" )))).query()

привело к сообщению:

line 1:16 no viable alternative at input '<EOF>'
  • 0
    @BartKiers: я добавил это как комментарий к твоему ответу. Еще раз спасибо.
  • 0
    Круто, спасибо, это всегда хорошая идея, чтобы скопировать и вставить точные сообщения об ошибках в исходное сообщение (вы можете редактировать свой вопрос после его отправки).
Показать ещё 1 комментарий
Теги:
antlr4
recursion
antlr

1 ответ

1
Лучший ответ

При добавлении правила lexer, которое потребляет (и пропускает) пробелы, у меня нет проблем.

Грамматика:

grammar T;

SPACE       : [ \t\r\n]+ -> skip
            ;
WITH        : 'WITH'
            ;
NAME        : ('a'..'z' | 'A'..'Z' | '0'..'9' | '-' | '_')+
            ;
query       : NAME (WITH query)?
            ;

будет соответствовать вводу a WITH b WITH c WITH d следующим образом:

Изображение 174551

Обратите внимание, что ваше правило NAME может быть записано следующим образом:

NAME        : [a-zA-Z0-9_-]+
            ;

Чтобы избавиться от сообщения EOF, просто введите точку входа в грамматику, которая заканчивается EOF:

parse : query EOF;

а затем выполните:

new TParser(...).parse()
  • 0
    Спасибо за ваш ответ! Когда я пробую вашу грамматику (я копирую / вставляю ее), я получаю следующую ошибку: 'строка 1:16 - нет приемлемой альтернативы при вводе' <EOF> ''.
  • 0
    Мой код: new TParser(new CommonTokenStream(new TLexer(new ANTLRInputStream( "hello WITH world" )))).query()
Показать ещё 4 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню