Решение может соответствовать входным данным, таким как «ID», используя несколько альтернатив: 1, 2 - PullRequest
3 голосов
/ 15 ноября 2011

Я пытаюсь определить простую функциональную грамматику языка, я почти закончил свои определения, но я не могу преодолеть следующие неясности.

[14:43:53] warning(200): mygrammar.g:14:11: Decision can match input such as "ATOM" using multiple alternatives: 1, 2 As a result, alternative(s) 2 were disabled for that input 

[14:43:53] warning(200): mygrammar.g:14:11: Decision can match input such as "ID" using multiple alternatives: 1, 2 As a result, alternative(s) 2 were disabled for that input

вот, что я думаю, соответствующие правила, чертеж почти идентичен для ATOM и ID:

program : (statement'.')* ;

statement : assignment
          | expression;

assignment : func '->' statement ((','statement)=> ',' statement)*
           | ID '->' expression
           | ATOM '->' ( string | number ); 

func : (ID '(' args ')')=> ID '(' args ')'; 

term : func
     | '(' expression ')'  
     | number
     | string
     | ID
     | ATOM ;

ATOM : ('A'..'Z'|'_')+;

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

вот дерево синтаксиса из ANTLRWorks

альтернативные идентификаторы http://www.vertigrated.com/images/id_alternatives.png

Вот грубый соломенный человек того, что я пытаюсь поддержать при разборе.

hypotenuse(a,b) -> 
  sqr(x) -> x * x,
  sqr(sqr(a) + sqr(b)). 

print(hypotnenuse(2,3)).

поэтому я должен иметь возможность поддерживать вложенность statements внутри functions

где -> - мой оператор присваивания, это один язык присваивания

где . - маркер конца моего заявления

Возможно ли даже разобрать ANTLR3?

1 Ответ

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

Несколько советов, которые сделают вашу грамматику менее двусмысленной:

  1. удалите '.' как символ конца утверждения.Замените его, скажем, на ';'.Оба являются только одним символом, и ';' не конфликтует с '.' внутри числа с плавающей запятой;
  2. создает правило лексера, соответствующее значению с плавающей запятой;
  3. за функцией следует одинили более операторов, но не имеет очевидного конца (за исключением функции "main", которая теперь заканчивается на '.').Вы должны либо сообщить парсеру, где заканчивается функция (а не только «основная» функция), или должны ввести правило, которое соответствует «внутренней» функции, которая не имеет несколько конечных statement с, ноодин expression;
  4. вам действительно нужен expression в вашем правиле statement?И то и другое может быть функцией (сделайте это, опять же, неоднозначно).

Это лишь некоторые из проблем, связанных с тем, как вы определили свой язык.Если бы я был тобой, я бы не стал продолжать в том же духе: ты мог бы исправить некоторые вещи с помощью предикатов, но изменение чего-либо в другом месте откроет еще одну банку с червями.Я советую вам кардинально изменить свой язык.

Если вы не хотите изменять его, просто удалите все предикаты из вашей грамматики и вставьте следующую строку в раздел options {...}:

backtrack=true;

, который (казалось бы) волшебным образом удалит все предупреждения, касающиеся неоднозначных правил, но это не рекомендуемое исправление.Таким образом, ANTLR выберет для вас деревья разбора, когда столкнется с неоднозначностью, что может привести к непредсказуемому поведению, а при большом вводе это приведет к увеличению времени разбора.Опять же, это не то, что я бы пошел!См. Вики для получения дополнительной информации о глобальном возврате: http://www.antlr.org/wiki/display/ANTLR3/How+to+remove+global+backtracking+from+your+grammar

...