Пошаговое устранение этой непрямой левой рекурсии

Я видел этот алгоритм можно использовать для удаления всей левой рекурсии. Тем не менее, у меня возникают проблемы с этой конкретной грамматикой:

A -> Cd
B -> Ce
C -> A | B | f

Что бы я ни пытался, я в конечном итоге получаю циклы или грамматику, которая все еще является косвенной леворекурсивной.

Как правильно реализовать алгоритм в этой грамматике?


person Flion    schedule 14.04.2013    source источник
comment
Это следует перенести на cstheory.stackexchange.com, так как это не имеет ничего общего с программированием, а только с теорией CS.   -  person Parth Sane    schedule 25.04.2016


Ответы (2)


Правило состоит в том, что вы сначала устанавливаете какой-то порядок для нетерминалов, а затем находите все пути, где происходит непрямая рекурсия.

В этом случае порядок будет 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
person Bokisha    schedule 10.01.2014

Разобрался уже.

Меня смутило то, что в этом порядке алгоритм, казалось, ничего не делал, поэтому я решил, что это должно быть неправильно, и начал заменять A -> Cd в первой итерации (игнорируя j не может выходить за пределы i), попадая в бесконечные циклы.

1) Переупорядочив правила:

C -> A | B | f 
A -> Cd
B -> Ce

2) заменить C в A -> 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

ууууу! грамматика без левой рекурсии!

person Flion    schedule 14.04.2013
comment
Разве ты не можешь просто C -> fD с D -> eps | dD | eD - person Howard; 14.04.2013
comment
ха, да, ты прав! хотя приведенное выше было хорошей практикой для алгоритма, это действительно было бы самым простым переписыванием. Спасибо. Есть ли какое-то общее правило, которое вы использовали для этого, или это просто здравый смысл, который исходит из практики? ;) - person Flion; 15.04.2013
comment
В шаге 5 опечатка, первое производство B. Должно быть BdA'e - person Sagar Rakshe; 25.11.2013