Зубр, как описать необязательный синтаксис в грамматике без конфликтов сдвига-уменьшения? - PullRequest
0 голосов
/ 11 сентября 2018

У меня есть файл, который описан с грамматикой.Он имеет раздел, который может состоять из одного или двух видов содержимого, и может быть в произвольном порядке:

...
type_a_thing
type_b_thing
type_b_thing
type_a_thing
....

Или просто

...
type_a_thing
...

или

...
type_b_thing
type_b_thing
...

или любые комбинации, в любом количестве случаев.Оба типа type_a_thing и type_b_thing имеют четко определенную структуру.Мне удалось описать это так, чтобы синтаксический анализатор работал, но я все еще получаю ошибки сдвига / уменьшения.Я загрузил здесь минимальный пример:

https://github.com/waszil/minimal_bison_parser

Это правильный способ решения этой проблемы?Я делаю это неправильно?Я много чего перепробовал, проверил файл .output, сгенерированный bison, с подробным флагом, но я не знаю, как это сделать правильно.Она в некоторой степени похожа на проблему грамматики с вложенным списком, описанную в книге Flex & Bison O'Reilly, но не та же

Спасибо за любые подсказки!

1 Ответ

0 голосов
/ 12 сентября 2018

Посмотрите на эту часть вашей грамматики:

contents:
    foobar
    | contents foobar
    ;
foobar:
    foos
    | bars
    ;
foos:
    foo
    | foos foo
    ;
bars:
    bar
    | bars bar
;

Итак, contents - это список foobar с, а foobar - это либо список foo с, либо списокbar s.Это неоднозначно, потому что вход, состоящий из двух последовательных foo с, может быть проанализирован как contents путем интерпретации двух foo с как одного foobar, содержащего два foo с, или как два foobar с.содержащий один foo каждый.

Простой способ избавиться от этой неоднозначности - отказаться от внутренних списков:

contents: foobar | contents foobar;

foobar: foo | bar;

Если вам нужны последовательные foo s для обработки по-разному,вы все еще можете обнаружить их во время пост-обработки.Если вам абсолютно необходимо обработать это в грамматике, вы можете реструктурировать грамматику так, чтобы за foos мог следовать только bars (не другой foos) или наоборот.

...