Устранение левой рекурсии — различия между версиями
Shagal (обсуждение | вклад) м (→Литература) |
Shagal (обсуждение | вклад) |
||
| Строка 3: | Строка 3: | ||
}} | }} | ||
{{Определение | {{Определение | ||
| − | |definition=Говорят, что КС-грамматика <tex>\Gamma</tex> содержит '''левую рекурсию''', если в ней существует вывод вида <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> может применяться бесконечно долго, так и не выработав некий терминальный символ, который можно было бы сравнить со строкой. Поэтому требуется преобразование грамматики, которое бы устранило левую рекурсию. |
| − | |||
| + | Левая рекурсия может быть: | ||
| + | * непосредственной(immidiate) | ||
| + | <tex>A \Rightarrow A\alpha</tex> | ||
| + | * произвольной(indirect) | ||
| + | <tex>A_0 \rightarrow A_1\alpha</tex> | ||
| + | |||
| + | <tex>A_1 \rightarrow A_0\alpha</tex> | ||
==Устранение непосредственной левой рекурсии== | ==Устранение непосредственной левой рекурсии== | ||
| Строка 26: | Строка 32: | ||
</ol> | </ol> | ||
| − | Этот алгоритм не устраняет левую рекурсию,вызванную двумя или более шагами порождения. | + | Этот алгоритм не устраняет произвольную левую рекурсию,вызванную двумя или более шагами порождения. |
===Пример=== | ===Пример=== | ||
Версия 18:17, 16 декабря 2012
| Определение: |
| Говорят, что контекстно-свободная(КС) грамматика содержит непосредственную левую рекурсию, если она содержит правило вида . |
| Определение: |
| Говорят, что КС-грамматика содержит левую рекурсию(left recursion), если в ней существует вывод вида . |
Методы нисходящего разбора(top=down parsers) не в состоянии работать с леворекурсивными грамматиками. Проблема в том, что продукция вида может применяться бесконечно долго, так и не выработав некий терминальный символ, который можно было бы сравнить со строкой. Поэтому требуется преобразование грамматики, которое бы устранило левую рекурсию.
Левая рекурсия может быть:
- непосредственной(immidiate)
- произвольной(indirect)
Содержание
Устранение непосредственной левой рекурсии
Опишем процедуру, устраняющую все правила вида , для фиксированного нетерминала .
- Запишем все правила вывода из в виде:
, где
- — непустая последовательность терминалов и нетерминалов ();
- — непустая последовательность терминалов и нетерминалов, не начинающаяся с .
- Заменим правила вывода из на .
- Создадим новый нетерминал .
Этот алгоритм не устраняет произвольную левую рекурсию,вызванную двумя или более шагами порождения.
Пример
S леворекурсивен, так как , но эта рекурсия не является непосредственной.
Устранение произвольной левой рекурсии
Пусть — множество всех нетерминалов.
for i = 1 to n
for j = 1 to i – 1
рассмотреть все правила вывода из : .
заменить каждое правило на .
устранить непосредственную левую рекурсию для .
Таким образом, после применения алгоритма все правила вывода имеют вид:
- , где — терминал, — произвольный нетерминал;
- , где , — нетерминалы из исходной грамматики;
- , где — новый нетерминал, — нетерминал из исходной грамматики.
Если теперь перенумеровать нетерминалы, сохранив порядок для старых и присвоив всем новым меньшие номера, то все правила будут иметь вид:
- , где — терминал;
- , где .
Алгоритм устранения левой рекурсии
Для произвольной грамматики левую рекурсию можно устранить следующим образом:
- Воспользуемся алгоритмом удаления -правил. Получим грамматику без -правил для языка .
- Воспользуемся алгоритмом устранения произвольной левой рекурсии.
- Если присутствовал в языке исходной грамматики, добавим новый начальный символ и правила .
Литература
- Хопкрофт Д., Мотвани Р., Ульман Д. — Введение в теорию автоматов, языков и вычислений, 2-е изд. : Пер. с англ. — Москва, Издательский дом «Вильямс», 2002. — 528 с. : ISBN 5-8459-0261-4 (рус.)
- Robert C. Moore — Removing Left Recursion from Context-Free Grammars