Устранение левой рекурсии — различия между версиями
| Строка 6: | Строка 6: | ||
}} | }} | ||
| − | + | ==Устранение непосредственной левой рекурсии== | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
Опишем процедуру, устраняющую все правила вида <tex>A \rightarrow A\alpha</tex> для фиксированного нетерминала <tex>A</tex>. | Опишем процедуру, устраняющую все правила вида <tex>A \rightarrow A\alpha</tex> для фиксированного нетерминала <tex>A</tex>. | ||
| Строка 30: | Строка 22: | ||
</ol> | </ol> | ||
| − | + | ==Устранение произвольной левой рекурсии== | |
Пусть множество всех нетерминалов <tex>N = \lbrace A_1, A_2, \ldots , A_n \rbrace</tex> | Пусть множество всех нетерминалов <tex>N = \lbrace A_1, A_2, \ldots , A_n \rbrace</tex> | ||
<div> | <div> | ||
| Строка 56: | Строка 48: | ||
*<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> | ||
| + | Приведем алгоритм, позволяющий для к.с. грамматики ''без <tex> \varepsilon </tex>-правил'' построить эквивалентную ей к.с. грамматику (без <tex> \varepsilon </tex>-правил), не содержащую левой рекурсии. | ||
| + | |||
| + | ==Алгоритм устранения левой рекурсии== | ||
| + | |||
| + | Для произвольной грамматики <tex>\Gamma</tex> левую рекурсию можно устранить следующим образом: | ||
| + | #Воспользоваться [[Удаление_eps-правил_из_грамматики | алгоритмом удаления <tex> \varepsilon </tex>-правил]]. Получим грамматику без <tex> \varepsilon </tex>-правил для языка <tex>L(\Gamma) \setminus \lbrace \epsilon \rbrace</tex> | ||
| + | #Воспользоваться алгоритмом устранения произвольной левой рекурсии | ||
| + | #Если <tex>\epsilon</tex> присутствовал в языке исходной грамматики, добавить новый начальный символ <tex>S'</tex> и правила <tex>S' \rightarrow S \, | \, \epsilon </tex> | ||
| + | |||
| + | |||
==Литература== | ==Литература== | ||
* ''Хопкрофт Д., Мотвани Р., Ульман Д.'' — '''Введение в теорию автоматов, языков и вычислений''', 2-е изд. : Пер. с англ. — Москва, Издательский дом «Вильямс», 2002. — 528 с. : ISBN 5-8459-0261-4 (рус.) | * ''Хопкрофт Д., Мотвани Р., Ульман Д.'' — '''Введение в теорию автоматов, языков и вычислений''', 2-е изд. : Пер. с англ. — Москва, Издательский дом «Вильямс», 2002. — 528 с. : ISBN 5-8459-0261-4 (рус.) | ||
Версия 03:48, 27 ноября 2011
| Определение: |
| Говорят, что контекстно-свободная(к.с.) грамматика содержит непосредственную левую рекурсию, если она содержит правило вида . |
| Определение: |
| Говорят, что к.с. грамматика содержит левую рекурсию, если в ней существует вывод вида . |
Содержание
Устранение непосредственной левой рекурсии
Опишем процедуру, устраняющую все правила вида для фиксированного нетерминала .
- Запишем все правила вывода из в виде
, где
- - непустая последовательность терминалов и нетерминалов ()
- - непустая последовательность терминалов и нетерминалов, не начинающаяся с .
- Заменим правила вывода из на:
- И создадим новый нетерминал
Устранение произвольной левой рекурсии
Пусть множество всех нетерминалов
for i = 1 to n {
for j = 1 to i – 1 {
рассмотреть все правила вывода из :
заменить каждое правило на
}
устранить непосредственную левую рекурсию для
}
Инвариант: после итераций внутреннего цикла для
- для правые части правил вывода из не начинаются с
- правые части правил вывода из не начинаются с
- правые части правил вывода не начинаются с добавленных алгоритмом нетерминалов
- грамматика не содержит ε-правил
(проверяется индукцией по парам )
Таким образом, после применения алгоритма все правила вывода имеют вид
- , где - терминал, - произвольный нетерминал
- , где , - нетерминалы из исходной грамматики
- , где - новый нетерминал, - нетерминал из исходной грамматики
Если теперь перенумеровать нетерминалы, сохранив порядок для старых и присвоив всем новым меньшие номера, то все правила будут иметь вид
- , где - терминал
- , где
Приведем алгоритм, позволяющий для к.с. грамматики без -правил построить эквивалентную ей к.с. грамматику (без -правил), не содержащую левой рекурсии.
Алгоритм устранения левой рекурсии
Для произвольной грамматики левую рекурсию можно устранить следующим образом:
- Воспользоваться алгоритмом удаления -правил. Получим грамматику без -правил для языка
- Воспользоваться алгоритмом устранения произвольной левой рекурсии
- Если присутствовал в языке исходной грамматики, добавить новый начальный символ и правила
Литература
- Хопкрофт Д., Мотвани Р., Ульман Д. — Введение в теорию автоматов, языков и вычислений, 2-е изд. : Пер. с англ. — Москва, Издательский дом «Вильямс», 2002. — 528 с. : ISBN 5-8459-0261-4 (рус.)