Устранение левой рекурсии — различия между версиями
Shagal (обсуждение | вклад) (→Устранение непосредственной левой рекурсии) |
Shagal (обсуждение | вклад) (→Алгоритм устранения произвольной левой рекурсии) |
||
| Строка 32: | Строка 32: | ||
for все нетерминалы <tex>A_i</tex> | for все нетерминалы <tex>A_i</tex> | ||
for все нетерминалы <tex>A_j</tex>, такие, что <tex> 1 \leq j < i </tex> и | for все нетерминалы <tex>A_j</tex>, такие, что <tex> 1 \leq j < i </tex> и | ||
| − | рассмотреть все правила вывода из <tex>A_j</tex>: <tex>A_j \ | + | рассмотреть все правила вывода из <tex>A_j</tex>: <tex>A_j \Rightarrow \delta_1 | \ldots | \delta_k</tex>. |
| − | заменить каждое правило <tex>A_i \ | + | заменить каждое правило <tex>A_i \Rightarrow A_j \gamma</tex> на <tex>A_i \Rightarrow \delta_1\gamma | \ldots | \delta_k\gamma</tex>. |
устранить непосредственную левую рекурсию для <tex>A_i</tex>. | устранить непосредственную левую рекурсию для <tex>A_i</tex>. | ||
</div> | </div> | ||
| − | + | После <tex>i</tex> итерации внешнего цикла в любой продукции вида <tex> A_k \Rightarrow A_l\alpha </tex> где <tex> i > k </tex> будет <tex> l > k</tex>. | |
| − | + | В результате после каждой итерации растет нижний предел m всех продукций вида <tex>A_i \Rightarrow A_m\alpha</tex> до тех пор, пока не будет достигнуто <tex>m \geq i</tex>. Затем из <tex>A_i</tex> устраняется непосредственная левая рекурсия и достигается m > i. | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | После <tex>i | ||
| − | В результате после каждой итерации растет нижний предел m | ||
| Строка 55: | Строка 46: | ||
#Воспользуемся алгоритмом ''устранения произвольной левой рекурсии''. | #Воспользуемся алгоритмом ''устранения произвольной левой рекурсии''. | ||
#Если <tex>\varepsilon</tex> присутствовал в языке исходной грамматики, добавим новый начальный символ <tex>S'</tex> и правила <tex>S' \rightarrow S \, | \, \varepsilon </tex>. | #Если <tex>\varepsilon</tex> присутствовал в языке исходной грамматики, добавим новый начальный символ <tex>S'</tex> и правила <tex>S' \rightarrow S \, | \, \varepsilon </tex>. | ||
| − | |||
| − | |||
==Литература== | ==Литература== | ||
Версия 11:56, 7 января 2013
| Определение: |
| Говорят, что контекстно-свободная(КС) грамматика содержит непосредственную левую рекурсию, если она содержит правило вида . |
| Определение: |
| Говорят, что КС-грамматика содержит левую рекурсию(left recursion), если в ней существует вывод вида . |
Методы нисходящего разбора(top-down parsers) не в состоянии работать с леворекурсивными грамматиками. Проблема в том, что продукция вида может применяться бесконечно долго, так и не выработав некий терминальный символ, который можно было бы сравнить со строкой. Поэтому требуется преобразование грамматики, которое бы устранило левую рекурсию.
Устранение непосредственной левой рекурсии
Опишем процедуру, устраняющую все правила вида , для фиксированного нетерминала .
- Запишем все правила вывода из в виде:
, где
- — непустая последовательность терминалов и нетерминалов ();
- — непустая последовательность терминалов и нетерминалов, не начинающаяся с .
- Заменим правила вывода из на .
- Создадим новый нетерминал .
Нетерминал A порождает те же строки, что и ранее, но без левой рекурсии. Эта процедура устраняет все непосредственные рекурсии из продукций для A, при условии, что ни одна строка не является .
Алгоритм устранения произвольной левой рекурсии
Пусть — множество всех нетерминалов.
for все нетерминалы for все нетерминалы , такие, что и рассмотреть все правила вывода из : . заменить каждое правило на . устранить непосредственную левую рекурсию для .
После итерации внешнего цикла в любой продукции вида где будет . В результате после каждой итерации растет нижний предел m всех продукций вида до тех пор, пока не будет достигнуто . Затем из устраняется непосредственная левая рекурсия и достигается m > i.
Для произвольной грамматики левую рекурсию можно устранить следующим образом:
- Воспользуемся алгоритмом удаления -правил. Получим грамматику без -правил для языка .
- Воспользуемся алгоритмом устранения произвольной левой рекурсии.
- Если присутствовал в языке исходной грамматики, добавим новый начальный символ и правила .
Литература
- Хопкрофт Д., Мотвани Р., Ульман Д. — Введение в теорию автоматов, языков и вычислений, 2-е изд. : Пер. с англ. — Москва, Издательский дом «Вильямс», 2002. — 528 с. : ISBN 5-8459-0261-4 (рус.)
- Robert C. Moore — Removing Left Recursion from Context-Free Grammars