Задача с обратным выводом с простой суммой и умножением грамматики

У меня возникли проблемы с пониманием того, как, используя анализатор снизу вверх и, например, строку ввода 1 + 2 * 3, перейдите от "снизу" к "вершине".

Вот грамматика, которую я использую (я бы сказал, что она правильная, так как она найдена в Crafting a Compiler)

E = E plus T
  | T;

T = T times integer
  | integer;

Это мой обратный вывод:

int(1)
T(1)
E(1)
E(1) plus int(2)
E(1) plus T(2)
E(1) plus E(2)
E(1) plus E(2) times int(3)
E(1) plus E(2) times E(3) <-- can't do anything here

Проблема в том, что каждый раз, когда я получаю целое число в качестве входных данных, оно будет автоматически "преобразовано" в E,

Я уверен, что данная грамматика верна. Я также попробовал это в sablecc с некоторыми входными строками (используя созданный мной посетитель Pretty Printer), и все они дают правильный результат.

Таким образом, я знаю, что проблема во мне, а не в самой грамматике. Что я делаю не так, тогда?

Спасибо!

1 ответ

Решение

Конфликт сдвига-уменьшения является наиболее распространенным типом конфликта, встречающегося в грамматике. В вашем случае T(2) может быть уменьшено до E(2), или времена могут быть сдвинуты. По умолчанию большинство генераторов парсеров предпочитают сдвигать, а не уменьшать. Но они все равно уменьшат T(1) до E(1), потому что они знают, что нет смысла сдвигать плюс после T.

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