ANTLR неясно несколько альтернатив

#antlr #grammar #antlr3

#antlr #грамматика #antlr3

Вопрос:

У меня есть эта грамматика для соответствия простым логическим предикатам в ANTLR.

 exp :   or
    ;

or  :   and ('|' or)*
    ;

and :   unit ('amp;' and)*
    ;

unit    :   '(' or ')' |
        STRING
    ;

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

STRING
    :  ''' ( ESC_SEQ | ~('\'|''') )* '''
    ;

fragment
HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ;

fragment
ESC_SEQ
    :   '\' ('b'|'t'|'n'|'f'|'r'|'"'|'''|'\')
    |   UNICODE_ESC
    |   OCTAL_ESC
    ;

fragment
OCTAL_ESC
    :   '\' ('0'..'3') ('0'..'7') ('0'..'7')
    |   '\' ('0'..'7') ('0'..'7')
    |   '\' ('0'..'7')
    ;

fragment
UNICODE_ESC
    :   '\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
    ;
  

Я получаю предупреждение Decision can match input such as "'amp;'" using multiple alternatives: 1, 2 , а также одно для or правила. Я знаю, что это предупреждение появляется, когда в грамматике есть двусмысленности, но я действительно не вижу, в чем заключается двусмысленность. Я также не понимаю предупреждающего сообщения, потому что в нем говорится, что ввод ‘amp;’ имеет несколько альтернатив, но ‘amp;’ сам по себе не должен быть допустимым вводом. Может кто-нибудь указать на двусмысленность? Я беспокоюсь, что это испортит меня позже, когда грамматика станет более сложной.

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

1. Вы редактировали свой код или сообщение об ошибке? В вашей ошибке указано «Решение», но я думаю, что это относится к and вашей грамматике.

Ответ №1:

Я думаю, что вместо этого:

 or  :   and ('|' or)*
    ;

and :   unit ('amp;' and)*
    ;
  

вы хотите, чтобы это:

 or  :   and ('|' and)*
    ;

and :   unit ('amp;' unit)*
    ;
  

Форма, которую вы получили, неоднозначна, потому что, когда она обрабатывает это вложенное or (или and ), она не знает, следует ли продолжать повторять, поглощая следующее | (или amp; ) или если оно должно вернуться к внешнему и позволить ему обработать его.