Изменения

Перейти к: навигация, поиск

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

492 байта добавлено, 22:34, 18 января 2013
Алгоритм устранения произвольной левой рекурсии
Упорядочим нетерминалы и будим добиваться того, чтобы не было правил вида <tex>A_i \to A_j\alpha</tex>, где <tex>j \le i</tex>.
Можно заметить, что если Если данное условие выполняется для всех<tex>A_i</tex>, то в грамматике не будет нет <tex>A_i \to^* A_i</tex>, а значит надо не будет только устранить непосредственную левую рекурсию для <tex>A_i</tex>левой рекурсии.  
Пусть <tex>N = \lbrace A_1, A_2, \ldots , A_n \rbrace</tex> {{---}} упорядоченное множество всех нетерминалов.
Если <tex>\varepsilon</tex> присутствовал в языке исходной грамматики, добавим новый начальный символ <tex>S'</tex> и правила <tex>S' \to S \, | \, \varepsilon </tex>.
 
После <tex>i</tex> итерации внешнего цикла в грамматике будут только правила вида <tex>A_i \to A_j\alpha</tex>, где <tex>j > i</tex>.
Можно заметить, что неравенство становится строгим только после применения алгоритма устранения непосредственной левой рекурсии. При этом добавляются новые нетерминалы, но по очевидным соображениям их можно не рассматривать в цикле.
На <tex>i</tex> итерации внешнего цикла все правила вида <tex>A_i \to A_j \gamma</tex> где <tex> j < i </tex> заменяются на <tex>A_i \to \delta_1\gamma | \ldots | \delta_k\gamma</tex> где <tex>A_j \to \delta_1 | \ldots | \delta_k</tex>. Очевидно, что одна итерация алгоритма не меняет язык, а значит язык получившийся в итоге грамматики совпадает с исходным.
 
===Асимптотика===
Анонимный участник

Навигация