Как удалить ANTLR3 Предупреждение «множественные альтернативы» - PullRequest
3 голосов
/ 11 марта 2012

Я нашел несколько вопросов, связанных с «множественными альтернативами» в стеке, но ничего не помогло. Вот часть моего g файла в antlr3.

statement:
    selection_stmt
    | expression_stmt 
    | compound_stmt
    | iteration_stmt
    | return_stmt
    ;

selection_stmt:
    IF OPENB expression CLOSB statement (ELSE statement)?
    ;

expression:
    (var ASSIGN expression) => assignment 
    | simple_expression
    ;

Проблема, с которой я сталкиваюсь, заключается в следующем предупреждении для фразы ELSE statement выше.

(200): Решение может соответствовать входным данным, таким как «ELSE», используя несколько альтернатив: 1, 2 В результате альтернатива (ы) 2 были отключено для этого входа

Может кто-нибудь объяснить мне, что здесь происходит? Спасибо.

P.S. Когда я использую синтаксический предикат как ((ELSE)=>ELSE statement)?, предупреждение исчезает. У меня тоже нет причин для этого.

1 Ответ

5 голосов
/ 11 марта 2012

Бхатия писал:

Может кто-нибудь объяснить мне, что здесь происходит? Спасибо.

Допустим, ваш ввод:

if (A) if (B) return 1 else return 2

Ваша грамматика неоднозначна: синтаксический анализатор не "знает", как это интерпретировать. Это можно сделать двумя способами (я добавил фигурные скобки, чтобы подчеркнуть, к чему if принадлежит блок else):

1

if (A) 
{
  if (B)
  {
    return 1
  }
  else
  {
    return 2
  }
}

enter image description here

2

if (A)
{
  if (B)
  {
    return 1
  }
}
else
{
  return 2
}

enter image description here

Бхатия написал:

P.S. Когда я использую синтаксический предикат как ((ELSE)=>ELSE statement)?, предупреждение исчезает. У меня тоже нет причин для этого.

Добавляя предикат до ELSE, вы заставляете синтаксический анализатор выбирать вариант № 1 (и синтаксический анализатор больше не предупреждает, потому что вы явно указываете ему выбирать альтернативу № 1 вместо № 2). Это приводит к тому, что не помещает туда предикат, но тогда ANTLR предупредит вас об этом и упомянет, что игнорирует параметр # 2, а также выберет # 1 (сообщение: "Как результат, альтернатива (ы) 2 были отключены для этого входа ").

Теперь, ответ на ваш вопрос в заголовке, "как убрать предупреждение" множественные альтернативы "?" , будет сделать вашу грамматику однозначной (или просто оставить предикат там, но понять, что там) никогда не будет синтаксическим анализом , как показано в варианте № 2!). Вы можете сделать это, введя какой-то оператор-блок-разделитель, такой как { и }. Или сделайте так, как это делает Python: сделайте так, чтобы количество пропущенных пробелов делало различие, которому принадлежат if и else. Выбор за вами.

...