Как избавиться от следующих нескольких альтернативных предупреждений в моей грамматике ANTLR3? - PullRequest
3 голосов
/ 14 ноября 2011
[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:\Users\Jarrod Roberson\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

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

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

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

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

и вот что эторассматривая альтернативу

statement : ATOM
          | expression
          | assignment
          | function
          ;

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

program : (statement'.')*;

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

синтаксическая диаграмма http://www.vertigrated.com/images/alternatives.png

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

1 Ответ

2 голосов
/ 14 ноября 2011

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

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

Ваш синтаксический анализатор может проанализировать следующий ввод:

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

в двух разных деревьях разбора:

enter image description here

и

enter image description here

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

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

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

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

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

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

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

...