Постепенное устранение этой косвенной левой рекурсии
Я видел этот алгоритм, который нужно использовать, чтобы удалить всю левую рекурсию.
Тем не менее у меня возникают проблемы с этой конкретной грамматикой:
A -> Cd
B -> Ce
C -> A | B | f
Независимо от того, что я пытаюсь, я заканчиваю петлями или грамматикой, которая по-прежнему остается косвенной левой рекурсивной.
Каковы шаги по правильному внедрению этого алгоритма в этой грамматике?
Ответы
Ответ 1
Правило заключается в том, что вы сначала устанавливаете какой-то порядок для нетерминалов, а затем находите все пути, в которых происходит косвенная рекурсия.
В этом случае порядок будет A < B < C, а возможные пути для рекурсии нетерминального C будут
C=> A => Cd
и
C=> B => Ce
поэтому новые правила для C будут
C=> Cd | Ce | f
теперь вы можете просто просто удалить прямую левую рекурсию:
C=> fC'
C'=> dC' | eC' | eps
и полученная нерекурсивная грамматика будет:
A => Cd
B => Ce
C => fC'
C' => dC' | eC' | eps
Ответ 2
Выяснил это уже.
Моя путаница заключалась в том, что в этом порядке алгоритм, казалось, ничего не делал, поэтому я решил, что это должно быть неправильно, и начал замену A → Cd на первой итерации (игнорирование j не может превысить i) попадание в бесконечные циклы.
1) Переупорядочивая правила:
C -> A | B | f
A -> Cd
B -> Ce
2) заменим C в → Cd
C -> A | B | f
A -> Ad | Bd | fd
B -> Ce
3) B еще не находится в диапазоне j, поэтому оставьте это и замените прямую левую рекурсию A
C -> A | B | f
A -> BdA' | fdA'
A'-> dA' | epsylon
B -> Ce
4) замените C в B → Ce
C -> A | B | f
A -> BdA' | fdA'
A'-> dA' | epsylon
B -> Ae | Be | fe
5) еще не сделано! также необходимо заменить новое правило B → Ae (производство A находится в диапазоне j)
C -> A | B | f
A -> BdA' | fdA'
A'-> dA' | epsylon
B -> BdA'e | fdA'e | Be | fe
6) заменить прямую левую рекурсию в произведениях B
C -> A | B | f
A -> BdA' | fdA'
A'-> dA' | epsylon
B -> fdA'eB' | feB'
B'-> dA'eB' | eB' | epsylon
Woohoo! левая рекурсивная грамматика!