Как решить сдвиг / уменьшить конфликт?
-
02-10-2019 - |
Вопрос
Я использую Кубок для создания паршира, который мне нужен для моей тезисы. У меня есть сдвиг / уменьшение конфликта в своей грамматике. У меня есть это правило производства:
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
Теперь я на самом деле хотел, чтобы это сдвинулось, поэтому я довольно хорошо с этим, но мой профессор сказал мне найти способ решить конфликт. Я слепой. Я всегда читал о конфликте, а для меня, а для меня это не кажется. Вы можете помочь мне?
PS: идентификатор, lparen "(" и Rparen ")" - это терминал, парларь и команда не.
Решение
Ваша проблема не в этих правилах вообще. Хотя Michael Mrozek отвечает является правильным подходом к разрешению «висных остальных проблем», он не понимает проблему под рукой.
Если вы посмотрите на сообщение об ошибке, вы видите, что сдвиг / уменьшение конфликта присутствует Когда Лексинг 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;
Он заставляет Кубок решить конфликт, принимая левый матч.