Удаление левой рекурсии

Следующая грамматика имеет левую рекурсию

E= E+T|T
T= T*F|F
F= a|b|c

Как удалить его? Есть ли какая-либо общая процедура его?

7
задан Prasoon Saurav 16 April 2010 в 10:16
поделиться

4 ответа

Да, существует общая процедура, см., Например, Википедия .

E = TE'
E'= (e) | +TE'
T = FT'
T'= (e) | *FT'
F = a | b | c

Следует отметить, что это изменяет ассоциативность + и * слева направо. То есть, если раньше a + b + c анализировался как (a + b) + c , теперь он анализируется как a + (b + c) ].

Это не проблема для сложения и умножения, но это может быть проблема, например, для вычитания и деления.

В статье в Википедии более подробно рассказывается о процедуре удаления левой рекурсии и ее тонкостях.

14
ответ дан 6 December 2019 в 09:18
поделиться

Как отмечали другие, существует общая процедура замены левой рекурсии правой рекурсией. Другие ответы хорошо показывают, как использовать эту общую процедуру для удаления левой рекурсии в данной грамматике.

Вот решение, которое реструктурирует данную грамматику способом, специфичным для этой грамматики.

E= T+E|T
T= F*T|F
F= a|b|c
2
ответ дан 6 December 2019 в 09:18
поделиться

продукция

E = E+T
  | T
T = T*F
  | F
F = a|b|c

переходит в

E= T ('+' T)*
T= F ('*' F)*
F= a|b|c

Для поддержания той же обработки, где дизъюнкция кулака E обрабатывается с помощью A (E, T) . в новой версии используется:

ret = T1;
while(set.more()) ret = A(ret, set.pop_front().T);
1
ответ дан 6 December 2019 в 09:18
поделиться

Общая процедура, например, находится в Википедии . Я продемонстрирую для E = E + T | T :

E - леворекурсивный нетерминал. + T - это ненулевая последовательность (альфа). T - это последовательность, которая не начинается с E (бета).

Создаем новый нетерминал для «отдыха», т.е. ненулевая последовательность. Это обрабатывает рекурсию.

E '= epsilon | + TE'

И мы модифицируем исходное правило, чтобы использовать новый нетерминал для обработки рекурсии.

E = TE '

3
ответ дан 6 December 2019 в 09:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: