Как решить сдвиг / уменьшить конфликт?

Я использую CUP для создания парсера, который мне нужен для моей диссертации. У меня есть конфликт сдвига / уменьшения в моей грамматике. У меня есть это правило производства:

command ::= IDENTIFIER | IDENTIFIER LPAREN parlist RPAREN;

и у меня есть это предупреждение:

Warning : *** Shift/Reduce conflict found in state #3
between command ::= IDENTIFIER (*) 
and     command ::= IDENTIFIER (*) LPAREN parlist RPAREN 
under symbol LPAREN

Теперь я действительно хотел, чтобы это изменилось, поэтому я вполне согласен с этим, но мой профессор сказал мне найти способ разрешить конфликт. Я слепой. Я всегда читал о конфликте if / else, но для меня это не так. Вы можете мне помочь?

PS: IDENTIFIER, LPAREN "(" и RPAREN ")" являются терминалами, parlist и команда не являются.

3 ответа

Решение

Ваша проблема не в этих правилах вообще. Хотя ответ Михаила Мрозека является правильным подходом к решению "висящей проблемы", он не понимает проблему под рукой.

Если вы посмотрите на сообщение об ошибке, вы увидите, что при смене LPAREN присутствует конфликт сдвига / уменьшения. Я уверен, что одни только правила не создадут конфликт.

Я не вижу твоей грамматики, поэтому я не могу тебе помочь. Но ваш конфликт, вероятно, когда command сопровождается другим правилом, которое начинается с LPAREN,

Посмотрите на любые другие правила, которые потенциально могут быть после command и начать с LPAREN, Затем вам нужно будет консолидировать правила. Существует очень хороший шанс, что ваша грамматика ошибочна для конкретного ввода.

У вас есть два производства:

command ::= IDENTIFIER
command ::= IDENTIFIER LPAREN parlist RPAREN;

Это конфликт сдвига / уменьшения, когда входные токены IDENTIFIER LPAREN, так как:

  • LPAREN может быть началом нового производства, которое вы не перечислили, и в этом случае парсер должен уменьшить IDENTIFIER уже в стеке в command, и имеют command LPAREN остальной
  • Они оба могут быть началом второго производства, поэтому это должно сместить LPAREN на стек рядом с IDENTIFIER и продолжайте читать, пытаясь найти parlist,

Вы можете исправить это, выполнив что-то вроде этого:

command ::= IDENTIFIER command2
command2 ::= LPAREN parlist RPAREN |;

Попробуйте установить приоритет:

precedence left     LPAREN, RPARENT;

Это заставляет CUP решить конфликт, приняв левый матч.

Другие вопросы по тегам