Как избавиться от следующих предупреждений о множественных альтернативах в моей грамматике ANTLR3?

#antlr #antlr3 #antlrworks

#antlr #antlr3 #antlrworks

Вопрос:

 [11:45:19] warning(200): mygrammar.g:14:57: Decision can match input such as "','" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
[11:45:19] warning(200): C:UsersJarrod Robersonmygrammar.g:14:57: Decision can match input such as "','" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
  

Я хочу иметь возможность вкладывать функции внутрь других функций.

 myfunction(x) ->
  sqr(a) -> a * a,
  y -> sqr(x).
  

вот строка, на которую он жалуется

 function : ID '(' args ')' '->' statement (',' statement)* ;
  

и вот что он рассматривает в качестве альтернативы

 statement : ATOM
          | expression
          | assignment
          | function
          ;
  

Я использую . в качестве правила завершения моего оператора

 program : (statement'.')*;
  

Вот как выглядит диаграмма synatx в ANTLRWorks

синтаксическая схема
(источник: vertigrated.com)

Мне действительно нравится, когда вещи компилируются / работают без каких-либо предупреждений. Как мне устранить это условие предупреждения?

Ответ №1:

Джаррод Роберсон писал:

Мне действительно нравится, когда вещи компилируются / работают без каких-либо предупреждений. Как мне устранить это условие предупреждения?

Ваш анализатор может анализировать следующие входные данные:

 f(x)-> g(y)-> y*y, x=y
  

в двух разных деревьях синтаксического анализа:

введите описание изображения здесь

и:

введите описание изображения здесь

Вы можете исправить это, заставив анализатор заглядывать вперед и убедиться, что есть ',' statement что-то впереди, прежде чем фактически сопоставлять эти правила. Вы можете сделать это, используя синтаксический предикат ( (...)=> часть) с указанным правилом внутри:

 function
  :  ID '(' args ')' '->' statement ((',' statement)=> ',' statement)* 
  ;
  

Однако вам не нужен предикат, если в вашем function правиле есть какой-то маркер «end», который вы не определили. Из ваших предыдущих вопросов и вашего примера:

 myfunction(x) ->
  sqr(a) -> a * a,
  y = sqr(x).
  

кажется, вы используете '.' как конец function . Если вы добавите это в свое function правило:

 function
  :  ID '(' args ')' '->' statement (',' statement)* '.'
  ;
  

вам вообще не нужен предикат.

Комментарии:

1. @JarrodRoberson, не стесняйтесь публиковать новый вопрос по этому поводу (если вы застряли на нем, то есть …).

2. . в конце функции является частью моего program правила. program : (statement'.')*; не является частью правила функции, таким образом, оно непротиворечиво.

3. @JarrodRoberson, а, понятно. Глядя на изображения дерева, я надеюсь, становится ясно, почему ANTLR жалуется: у function также должен быть очевидный конец. Я полагаю, что при использовании предиката будет создано дерево с первого изображения (и поэтому дерево с изображения 2 никогда не может быть создано!).

4. Я понял, что мой пример strawman был неправильным, в нем должно быть -> где = находится.

5. @JarrodRoberson, -> и = здесь не проблема. Отсутствие посторонних символов делает вашу грамматику неоднозначной. Вы понимаете, что анализатор может использовать две «дороги» во время синтаксического анализа "f(x)-> g(y)-> y*y, x=y" (см. Изображения)? Это потому, что вы явно не определили, когда a function заканчивается. Поскольку вы этого не сделали, последнее утверждение x=y (или x->y , это не имеет значения) может относиться к функции f , но также и к функции g . Добавляя предикат, вы просто подавляете предупреждение, в то время как вам следует обратиться к нему должным образом (исправить грамматику / язык).