Устранение левой рекурсии — различия между версиями
Строка 10: | Строка 10: | ||
<ol> | <ol> | ||
− | <li>Запишем все правила вывода из <tex>A</tex> в виде | + | <li>Запишем все правила вывода из <tex>A</tex> в виде: |
<tex>A \rightarrow A\alpha_1\,|\,\ldots\,|\,A\alpha_n\,|\,\beta_1\,|\,\ldots\,|\,\beta_m </tex>, где | <tex>A \rightarrow A\alpha_1\,|\,\ldots\,|\,A\alpha_n\,|\,\beta_1\,|\,\ldots\,|\,\beta_m </tex>, где | ||
<ul> | <ul> | ||
Строка 34: | Строка 34: | ||
</div> | </div> | ||
− | Таким образом, после применения алгоритма все правила вывода имеют вид | + | Таким образом, после применения алгоритма все правила вывода имеют вид: |
*<tex>A \rightarrow c \alpha </tex>, где <tex>c</tex> - терминал, <tex>A</tex> - произвольный нетерминал | *<tex>A \rightarrow c \alpha </tex>, где <tex>c</tex> - терминал, <tex>A</tex> - произвольный нетерминал | ||
*<tex>A_i \rightarrow A_j \alpha </tex>, где <tex>i < j</tex>, <tex>A_i , A_j</tex> - нетерминалы из исходной грамматики | *<tex>A_i \rightarrow A_j \alpha </tex>, где <tex>i < j</tex>, <tex>A_i , A_j</tex> - нетерминалы из исходной грамматики | ||
*<tex>A_i^{\prime} \rightarrow A_j \alpha </tex>, где <tex>A_i^{\prime}</tex> - новый нетерминал, <tex>A_j</tex> - нетерминал из исходной грамматики | *<tex>A_i^{\prime} \rightarrow A_j \alpha </tex>, где <tex>A_i^{\prime}</tex> - новый нетерминал, <tex>A_j</tex> - нетерминал из исходной грамматики | ||
− | Если теперь перенумеровать нетерминалы, сохранив порядок для старых и присвоив всем новым меньшие номера, то все правила будут иметь вид | + | Если теперь перенумеровать нетерминалы, сохранив порядок для старых и присвоив всем новым меньшие номера, то все правила будут иметь вид: |
*<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> |
Версия 06:57, 27 ноября 2011
Определение: |
Говорят, что контекстно-свободная(к.с.) грамматика содержит непосредственную левую рекурсию, если она содержит правило вида . |
Определение: |
Говорят, что к.с. грамматика | содержит левую рекурсию, если в ней существует вывод вида .
Содержание
Устранение непосредственной левой рекурсии
Опишем процедуру, устраняющую все правила вида
для фиксированного нетерминала .- Запишем все правила вывода из
- - непустая последовательность терминалов и нетерминалов ( )
- - непустая последовательность терминалов и нетерминалов, не начинающаяся с .
в виде:
, где
- Заменим правила вывода из на:
- Создадим новый нетерминал
Устранение произвольной левой рекурсии
Пусть
- множество всех нетерминаловfor i = 1 to n { for j = 1 to i – 1 { рассмотреть все правила вывода из: заменить каждое правило на } устранить непосредственную левую рекурсию для }
Таким образом, после применения алгоритма все правила вывода имеют вид:
- , где - терминал, - произвольный нетерминал
- , где , - нетерминалы из исходной грамматики
- , где - новый нетерминал, - нетерминал из исходной грамматики
Если теперь перенумеровать нетерминалы, сохранив порядок для старых и присвоив всем новым меньшие номера, то все правила будут иметь вид:
- , где - терминал
- , где
Алгоритм устранения левой рекурсии
Для произвольной грамматики
левую рекурсию можно устранить следующим образом:- Воспользуемся алгоритмом удаления . Получим грамматику без -правил -правил для языка
- Воспользуемся алгоритмом устранения произвольной левой рекурсии
- Если присутствовал в языке исходной грамматики, добавим новый начальный символ и правила
Литература
- Хопкрофт Д., Мотвани Р., Ульман Д. — Введение в теорию автоматов, языков и вычислений, 2-е изд. : Пер. с англ. — Москва, Издательский дом «Вильямс», 2002. — 528 с. : ISBN 5-8459-0261-4 (рус.)