2016-07-06 13 views
1

In Rascal, почему это происходит, когда есть расположение в позиции необязательной части производства, это вызывает неоднозначность? Например. "{ }" неоднозначен как Start1, в то время как он обрабатывает штраф как Start2 из следующей грамматики, которую я ожидал бы быть точно идентичной.Почему макет вокруг необязательных частей производства вызывает неоднозначность?

layout Layout        = " "?; 
start syntax Start1       = "{" "c"? "}"; 
start syntax Start2       = "{" "c" "}" 
              | "{" "}"; 

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

Очевидно, что здесь нет большого количества дубликатов, и Start2 - хороший вариант здесь, но это всего лишь пример. Я работаю с грамматикой со многими постановками, которые содержат три или четыре необязательные части, и в последнем случае обозначение, отображаемое в Start2, уже требует дублирования нефакультативных частей производства 2^4 = 16 раз, что действительно является хлопотным в моей мнение.

ответ

1

Ваша грамматика сначала расширена до того, как анализатор генерируется на что-то похожее на это:

layout Layout       = " "?; 
syntax " "?       = | " "; 
syntax Start1       = "{" Layout "c"? Layout "}"; 
syntax "c"?       = | "c"; 
lexical " "       = [\ ]; 
lexical "c"       = [c]; 
lexical "{"       = [{]; 
lexical "}"       = [}]; 
syntax Start2       = "{" Layout "c" Layout "}" 
             | "{" Layout "}"; 
syntax start[Start1] = Layout Start1 Layout; 
syntax start[Start2] = Layout Start2 Layout; 

Так для входа как { } (пространство между фигурной скобкой), пространство может быть получено с помощью первого экземпляра Макет в правой части правила Start1 или второй экземпляр макета. Так как синтаксический анализатор производит все деревья деривации, в этом случае разбор равен неоднозначно так сказать.

Обычно неоднозначность решается путем введения жадность используя ограничение последующей следующим образом:

layout Layout = " "? !>> " " 

или (что эквивалентно) как так:

layout Layout = " "? !>> [\ ] 

Ограничение действует как ограничение на Правило макета: оно ничего не выведет (даже пустую строку), если после него будет пробел. Это делает только первый вывод действительным тогда, когда пространство входит в первый экземпляр макета Start1. После этого есть }, который удовлетворяет ограничению, и синтаксический разбор однозначен.

+0

Спасибо за подробный ответ. Мне действительно было гораздо больше смысла, когда я увидел, как расширяется грамматика, и решение легко понять. Мне все еще кажется немного странным, но это необходимо. Не было бы полезно иметь вариант на вопросительном знаке (и звездочке), доступный для вас, когда вас не интересует расположение макета? Я могу представить, что это будет использовано довольно много. –

+0

Да, мы тоже об этом думали; но с нетерпением? или * может легко привести к ошибкам разбора, которые очень неожиданны и трудно отлаживаются. В этом отношении легче установить двусмысленность, чем ошибку синтаксического анализа. Декларативная неоднозначность также может вводить ошибки разбора, но по крайней мере ее явно видно. Тем не менее, мы думаем о том, чтобы вводить нетерпеливую семантику на лексическом уровне для регулярных подъязыка маркера, сохраняя общую контекстно-зависимую часть. Будущая работа! – jurgenv

 Смежные вопросы

  • Нет связанных вопросов^_^