Как решить сдвиг / уменьшить конфликт?
Я использую 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 решить конфликт, приняв левый матч.