Ошибка ANTLR: решение может соответствовать вводу, используя несколько альтернатив - PullRequest
1 голос
/ 29 октября 2011

Я не вижу, как справиться с ошибкой грамматики ANTLR:

****************error message*********
Decision can match input such as "{'+', '-'} IDENT" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
 |---> add: mult (('+'|'-') mult)*;
***************************************

Это в основном скопировано с примера Скотта, но я не вижу, почему его работа работает хорошо, но моя застряла икак из этого выбраться?

--------------- следующий образец.g ----------------

grammar Sample;

options { 
  language = Java;
}


 program
      :  'program' IDENT '='
          (constant| variable)*
          'begin'
          (statement)*
          'end' IDENT '.'
      ; 

constant:
       'constant' IDENT ':' type ':=' expression ';' 
      ;

type: 'integer';

variable: 'var' IDENT (',' IDENT)* ':' type  ';';


statement: 'var' IDENT ':=' INTEGER ';' ;

//expression

term: IDENT |'(' expression ')'|INTEGER;
negation: 'not'* term;
unary: ('+'|'-')* negation;
mult: unary (('*'|'/'|'mod') unary)*;

[XXX Ошибка для следующей строки]

add: mult (('+'|'-') mult)*;
relation: add (('='|'/='|'<'|'<=') add)*;
expression: (relation ('and'|'or') relation)*;


END : 'end';

CONSTANT : 'constant';

INTEGER: '0'| (('1'..'9') ('0'..'9')*);   

IDENT: ('a'..'z'|'A'..'Z')('a'..'z'|'A'..'Z'|'0'..'9')*;

WS: ('\n'|' '|'\t'|'r'|'\f')+ {$channel=HIDDEN;};

Ответы [ 2 ]

2 голосов
/ 29 октября 2011
  1. Хорошо упомянуть исходную веб-страницу, с которой вы взяли код. Я думаю, что здесь это Antlr3xtut .

Это в основном скопировано с примера Скотта, но я не понимаю, почему у него хорошо работает но мой застрял и как из него выйти?

Это потому, что вы скопировали неправильно.

Вместо правильного кода, как указано ниже:

expression
    :   relation (('and' | 'or') relation)*
    ;

Вы скопировали:

expression: (relation ('and'|'or') relation)*;

Вы можете определить ошибку? Например, размещение '(' непосредственно перед отношением. И из-за этого вы получаете ошибку Decision can match input such as "{'+', '-'} IDENT" using multiple alternatives:

enter image description here

Solution

Замените ваше правило выражения на то, что указано в примере scotts.

2 голосов
/ 29 октября 2011

Вы поставили круглые скобки в:

expression: (relation ('and'|'or') relation)*;

делает вашу грамматику неоднозначной: парсер не может решить, когда он увидит - IDENT, должен ли он быть частью add - или unary -рула.

Например, ваше правило expression теперь соответствует этому:

relation ('and'|'or') relation relation ('and'|'or') relation

Т.е. два relation правила, размещенные непосредственно друг за другом. Если синтаксический анализатор теперь натыкается на ввод, как это:

- A - B

синтаксический анализатор "видит" две возможности разбора этого ввода:

1 (унарное выражение и унарное выражение)

enter image description here

2 (унарное и сложное выражение)

enter image description here

Должно быть:

expression: relation (('and'|'or') relation)*;

вместо этого, поэтому никогда не может быть 2 последовательных выражений (и никакой двусмысленности!).

...