Устранение левой рекурсии — различия между версиями
Shagal (обсуждение | вклад) (→Алгоритм устранения произвольной левой рекурсии) |
Shagal (обсуждение | вклад) |
||
Строка 1: | Строка 1: | ||
{{Определение | {{Определение | ||
− | |definition=Говорят, что [[Контекстно-свободные грамматики, вывод, лево- и правосторонний вывод, дерево разбора|контекстно-свободная(КС) грамматика]] <tex>\Gamma</tex> содержит '''непосредственную левую рекурсию''', если она содержит правило вида <tex>A \Rightarrow A\alpha</tex>. | + | |definition=Говорят, что [[Контекстно-свободные грамматики, вывод, лево- и правосторонний вывод, дерево разбора|контекстно-свободная (КС) грамматика]] <tex>\Gamma</tex> содержит '''непосредственную левую рекурсию''', если она содержит правило вида <tex>A \Rightarrow A\alpha</tex>. |
}} | }} | ||
{{Определение | {{Определение | ||
− | |definition=Говорят, что КС-грамматика <tex>\Gamma</tex> содержит '''левую рекурсию(left recursion)''', если в ней существует вывод вида <tex>A \Rightarrow^* A\alpha</tex>. | + | |definition=Говорят, что КС-грамматика <tex>\Gamma</tex> содержит '''левую рекурсию (left recursion)''', если в ней существует вывод вида <tex>A \Rightarrow^* A\alpha</tex>. |
}} | }} | ||
− | Методы нисходящего разбора(top-down parsers) не в состоянии работать с леворекурсивными грамматиками. Проблема в том, что продукция вида <tex>A \Rightarrow^* A\alpha</tex> может применяться бесконечно долго, так и не выработав некий терминальный символ, который можно было бы сравнить со строкой. Поэтому требуется преобразование грамматики, которое бы устранило левую рекурсию. | + | Методы нисходящего разбора (top-down parsers) не в состоянии работать с леворекурсивными грамматиками. Проблема в том, что продукция вида <tex>A \Rightarrow^* A\alpha</tex> может применяться бесконечно долго, так и не выработав некий терминальный символ, который можно было бы сравнить со строкой. Поэтому требуется преобразование грамматики, которое бы устранило левую рекурсию. |
Строка 44: | Строка 44: | ||
<tex>A \Rightarrow S\alpha </tex> | <tex>A \Rightarrow S\alpha </tex> | ||
+ | |||
<tex>S \Rightarrow S\beta | A\gamma | b</tex> | <tex>S \Rightarrow S\beta | A\gamma | b</tex> | ||
Версия 14:45, 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