Bison Flex уменьшает / уменьшает конфликты при свисании еще с помощью среднего действия

В настоящее время я перемещаю свой забавный проект на bison/flex в качестве парсера, и у меня возникли проблемы с решением конфликта уменьшения / уменьшения:

// https://github.com/X39/yaoosl/blob/master/code-gen/yaoosl.y#L761-L766
ifthen: YST_IF YST_ROUNDO expression code_ifstart YST_ROUNDC codebody code_ifendnoelse
        | YST_IF YST_ROUNDO expression code_ifstart YST_ROUNDC ifthen_clsd YST_ELSE code_ifelse ifthen code_ifendelse
        ;
ifthen_clsd: codebody
           | YST_IF YST_ROUNDO expression code_ifstart YST_ROUNDC ifthen_clsd code_ifelse YST_ELSE ifthen_clsd code_ifendelse
           ;

Примечание: вещи с префиксом code_ - это промежуточные действия

Может ли кто-нибудь объяснить мне, как правильно решить эту проблему и почему решение "перейти" либо неверно, либо не сработало? Спасибо, X39

1 ответ

Решение

Поскольку эти два правила идентичны до code_ifelse (и предполагая, что code_ifelse - пустое правило, например действие в правиле), он не может определить, нужно ли сокращать code_ifelseдо или после YST_ELSE. Вы можете исправить это, приведя два правила в соответствие с порядкомcode_ifelse а также YST_ELSE.

Некоторые практические правила грамматики:

  • Не используйте символьные имена для одиночных символьных токенов, например '(' а также ')' - он просто запутывает вещи и затрудняет чтение и понимание грамматики.
  • Не используйте действия внутри правила без крайней необходимости - лучше создать правило с одним токеном с действием конечного правила, которое делает то, что вам нужно.
Другие вопросы по тегам