Устранение левой рекурсии — различия между версиями
(→Устранение непосредственной левой рекурсии) |
|||
Строка 5: | Строка 5: | ||
|definition=Говорят, что к.с. грамматика <tex>\Gamma</tex> содержит левую рекурсию, если в ней существует вывод вида <tex>A \Rightarrow^* A\alpha</tex>. | |definition=Говорят, что к.с. грамматика <tex>\Gamma</tex> содержит левую рекурсию, если в ней существует вывод вида <tex>A \Rightarrow^* A\alpha</tex>. | ||
}} | }} | ||
+ | |||
==Алгоритм устранения левой рекурсии== | ==Алгоритм устранения левой рекурсии== | ||
Приведем алгоритм, позволяющий для к.с. грамматики '''без ε-правил''' построить эквивалентную ей к.с. грамматику (без ε-правил), не содержащую левой рекурсии. | Приведем алгоритм, позволяющий для к.с. грамматики '''без ε-правил''' построить эквивалентную ей к.с. грамматику (без ε-правил), не содержащую левой рекурсии. | ||
Строка 12: | Строка 13: | ||
#Воспользоваться алгоритмом для новой грамматики | #Воспользоваться алгоритмом для новой грамматики | ||
#Если <tex>\epsilon</tex> присутствовал в языке исходной грамматики, добавить новый начальный символ <tex>S'</tex> и правила <tex>S' \rightarrow S \, | \, \epsilon </tex> | #Если <tex>\epsilon</tex> присутствовал в языке исходной грамматики, добавить новый начальный символ <tex>S'</tex> и правила <tex>S' \rightarrow S \, | \, \epsilon </tex> | ||
+ | |||
===Устранение непосредственной левой рекурсии=== | ===Устранение непосредственной левой рекурсии=== | ||
Опишем процедуру, устраняющую все правила вида <tex>A \rightarrow A\alpha</tex> для фиксированного нетерминала <tex>A</tex>. | Опишем процедуру, устраняющую все правила вида <tex>A \rightarrow A\alpha</tex> для фиксированного нетерминала <tex>A</tex>. | ||
Строка 57: | Строка 59: | ||
*<tex>B_i \rightarrow c \alpha </tex>, где <tex>c</tex> - терминал | *<tex>B_i \rightarrow c \alpha </tex>, где <tex>c</tex> - терминал | ||
*<tex>B_i \rightarrow B_j \alpha </tex>, где <tex>i < j</tex> | *<tex>B_i \rightarrow B_j \alpha </tex>, где <tex>i < j</tex> | ||
+ | |||
+ | ==Литература== | ||
+ | * ''Хопкрофт Д., Мотвани Р., Ульман Д.'' — '''Введение в теорию автоматов, языков и вычислений''', 2-е изд. : Пер. с англ. — Москва, Издательский дом «Вильямс», 2002. — 528 с. : ISBN 5-8459-0261-4 (рус.) |
Версия 02:08, 27 ноября 2011
Определение: |
Говорят, что к.с. грамматика | содержит непосредственную левую рекурсию, если она содержит правило вида .
Определение: |
Говорят, что к.с. грамматика | содержит левую рекурсию, если в ней существует вывод вида .
Содержание
Алгоритм устранения левой рекурсии
Приведем алгоритм, позволяющий для к.с. грамматики без ε-правил построить эквивалентную ей к.с. грамматику (без ε-правил), не содержащую левой рекурсии.
Для произвольной грамматики
левую рекурсию можно устранить следующим образом:- Воспользоваться алгоритмом удаления ε-правил. Получим грамматику без ε-правил для языка
- Воспользоваться алгоритмом для новой грамматики
- Если присутствовал в языке исходной грамматики, добавить новый начальный символ и правила
Устранение непосредственной левой рекурсии
Опишем процедуру, устраняющую все правила вида
для фиксированного нетерминала .Запишем все правила вывода из
в виде
где
- - непустая последовательность терминалов и нетерминалов ( )
- - непустая последовательность терминалов и нетерминалов, не начинающаяся с .
Заменим правила вывода из
на:
И создадим новый нетерминал
Устранение произвольной левой рекурсии
Пусть множество всех нетерминалов
- for i = 1 to n {
- for j = 1 to i – 1 {
- рассмотреть все правила вывода из
- заменить каждое правило на
- }
- устранить непосредственную левую рекурсию для
- for j = 1 to i – 1 {
- }
Инвариант: после
итераций внутреннего цикла для- для правые части правил вывода из не начинаются с
- правые части правил вывода из не начинаются с
- правые части правил вывода не начинаются с добавленных алгоритмом нетерминалов
- грамматика не содержит ε-правил
(проверяется индукцией по парам
)Таким образом, после применения алгоритма все правила вывода имеют вид
- , где - терминал, - произвольный нетерминал
- , где , - нетерминалы из исходной грамматики
- , где - новый нетерминал, - нетерминал из исходной грамматики
Если теперь перенумеровать нетерминалы, сохранив порядок для старых и присвоив всем новым меньшие номера, то все правила будут иметь вид
- , где - терминал
- , где
Литература
- Хопкрофт Д., Мотвани Р., Ульман Д. — Введение в теорию автоматов, языков и вычислений, 2-е изд. : Пер. с англ. — Москва, Издательский дом «Вильямс», 2002. — 528 с. : ISBN 5-8459-0261-4 (рус.)