Antlr: решение может совпадать с несколькими альтернативами (начиная с недопустимого токена?)

У меня есть грамматика в Antlr для анализа формата сохраняемого файла. Я разбил грамматику до той части, которая не работает, и я надеюсь, что кто-то сможет уточнить. Вот грамматика:

grammar OptFile;

parseFile returns [java.util.List<java.util.List<java.util.List<String>>> list] :
{ list = new java.util.ArrayList<List<List<String>>>(); }
vc=VARIABLESCAPTION v=variables oc=OBJECTIVECAPTION o=objective
{ list.add($v.list); list.add($o.list); }
;

variables returns [java.util.List<java.util.List<String>> list] : 
{ list = new java.util.ArrayList<List<String>>(); }
(v=variable { list.add($v.list); } )*
;

variable returns [java.util.List<String> list] : 
{ list = new java.util.ArrayList<String>(); }
n=characters ';' t=characters ';' lb=characters ';' ub=characters ';' 
{ list = new java.util.ArrayList(); list.add($n.string); list.add($t.string); list.add($lb.string); list.add($ub.string); }
;

objective returns [java.util.List<String> list] :
{ list = new java.util.ArrayList<String>(); }
t=characters ';' { list.add($t.string); }
( 
      'PIECEWISE;' pw=piecewisefunction { list.add($pw.string); }
    | 'REGULAR;' rf=characters ';' { list.add($rf.string); } 
);  

piecewisefunction returns [String string] :
( characters ';' characters ';' characters ';' characters ';' )* 
{ string = getText(); }
;   

characters returns [String string] :
( ~(';') )* { string = getText(); }
;

VARIABLESCAPTION : '--Variables:--' ;

OBJECTIVECAPTION : '--ObjectiveFunction:--' ;

Допустимый ввод должен выглядеть так:

--Variables--x;INTEGER;0;INFTY;y;CONTINUOUS;-12;13;--ObjectiveFunction--MAX;13x^27+SIN(y);

или как это

--Variables--x;INTEGER;12;20;--ObjectiveFunction--MAX;x;12;x;16;0,5x;16;x;20;

После '--Variables--' может быть любое количество переменных с четырьмя полями каждая, после '--ObjectiveFunction--' одно поле, а затем либо еще одно поле, либо произвольное множество "пакетов" из четырех полей.

Видимо, при компиляции с Antlr я получаю следующую ошибку:

warning(200): OptFile.g:26:37:
Decision can match input such as "OBJECTIVECAPTION {OBJECTIVECAPTION..VARIABLESCAPTION, 'PIECEWISE;'..'REGULAR;'} ';' 'PIECEWISE;' {OBJECTIVECAPTION..VARIABLESCAPTION, 'PIECEWISE;'..'REGULAR;'} ';' {OBJECTIVECAPTION..VARIABLESCAPTION, 'PIECEWISE;'..'REGULAR;'} ';' {OBJECTIVECAPTION..VARIABLESCAPTION, 'PIECEWISE;'..'REGULAR;'} ';' OBJECTIVECAPTION ';' 'PIECEWISE;'" using multiple alternatives: 1,2
As a result, alternative(s) 2 were disabled for that input

Мои вопросы сейчас:

  1. Как может ввод вообще начинаться с OBJECTIVECAPTION, насколько я понимаю, ввод для моей грамматики должен начинаться с VARIABLESCAPTION.
  2. Что мне нужно изменить, чтобы эта грамматика заработала?

person Skrodde    schedule 07.08.2012    source источник


Ответы (1)


Сообщение об ошибке может быть немного загадочным, но проблема в производстве variables, оно определяет ноль или более вхождений variable. Переменная может начинаться с ввода, показанного в сообщении об ошибке, но за variables также может следовать тот же ввод, который происходит в среде ее вызова. Таким образом, существует проблема выбора между продолжением в variables (альтернатива 1) и его завершением (альтернатива 2).

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

Чтобы исправить это, вы можете ввести разделитель для списка, чтобы стало ясно, когда следует прекратить сбор дополнительных вхождений variable, например

parseFile : VARIABLESCAPTION variables '.' OBJECTIVECAPTION objective ;

РЕДАКТИРОВАТЬ по Asker:

Я попробовал этот подход, и он отлично работает, но только если точка, которая используется в качестве символа разделения, добавлена ​​в список символов, которые необходимо игнорировать, т.е. строку кода для characters необходимо изменить:

characters : ( ~(';' | '.') )*;

После этого все работает нормально.

person Gunther    schedule 07.08.2012