Устранение левой рекурсии
Определение: |
Говорят, что контекстно-свободная (КС) грамматика содержит непосредственную левую рекурсию (direct left recursion), если она содержит правило вида . |
Определение: |
Говорят, что КС-грамматика | содержит левую рекурсию (left recursion), если в ней существует вывод вида .
Методы нисходящего разбора (top-down parsers) не в состоянии работать с леворекурсивными грамматиками. Проблема в том, что продукция вида может применяться бесконечно долго, так и не выработав некий терминальный символ, который можно было бы сравнить со строкой. Поэтому требуется преобразование грамматики, которое бы устранило левую рекурсию.
Устранение непосредственной левой рекурсии
Опишем процедуру, устраняющую все правила вида
, для фиксированного нетерминала .- Запишем все правила вывода из
- — непустая последовательность терминалов и нетерминалов ( );
- — непустая последовательность терминалов и нетерминалов, не начинающаяся с .
в виде:
, где
- Заменим правила вывода из на .
- Создадим новый нетерминал .
Изначально нетерминал
порождает сроки вида . В новой грамматике нетерминал порождает , а порождает строки вида . Из этого очевидно, что изначальная грамматика эквивалентна новой.Алгоритм устранения произвольной левой рекурсии
Пусть
— упорядоченное множество всех нетерминалов.for все нетерминалыfor все нетерминалы , такие, что и рассмотреть все правила вывода из : . заменить каждое правило на . устранить непосредственную левую рекурсию для .
На
итерации внешнего цикла все правила вида где заменяются на где . Таким образом остается только избавиться от непосредственной рекурсии для . Очевидно, что одна итерация алгоритма не меняет язык, а значит язык получившийся в итоге грамматики совпадает с исходным.Алгоритм не работает для грамматик с алгоритмом удаления . -правил
переходами и с грамматиками имеющими . Поэтому для произвольной грамматики необходимо сначала воспользоваться алгоритмомПроблема этого алгоритма в том, что в зависимости от порядка нетерминалов в множестве размер грамматки может получиться экспоненциальным.
Пример
для
Упорядочим множество нетерминалов по возрастанию индексов. Легко заметить, что правила для
будут представлять из себя все двоичные вектора длины , а значит размер грамматики будет экспоненциальным. Если упорядочить нетерминалы по убыванию в грамматике изменений не будет.Пример
Дана грамматика
Среди правил
непосредственной рекурсии нет, поэтому во время первой итерации внешнего цикла ничего не происходит. Во время второй итерации внешнего цикла правило переходит в .Грамматика имеет вид
Устраняем левую рекурсию для
Литература
- Хопкрофт Д., Мотвани Р., Ульман Д. — Введение в теорию автоматов, языков и вычислений, 2-е изд. : Пер. с англ. — Москва, Издательский дом «Вильямс», 2002. — 528 с. : ISBN 5-8459-0261-4 (рус.)
- Robert C. Moore — Removing Left Recursion from Context-Free Grammars