Алгоритм нисходящего разбора с возвратами
Рассмотрим алгоритм нисходящего разбора с возвратами. Для реализации алгоритма будем использовать два магазина (и ) и счетчик, в котором будет находиться текущая позиция входного указателя.
Вход: Нелеворекурсивная КС-грамматика и входная цепочка . Предполагается, что правила из занумерованы числами .
Выход: Один левый разбор цепочки , если таковой существует. В противном случае – слово «ошибка».
Метод:
1. Для каждого нетерминала упорядочить альтернативы. Пусть - индекс -ой альтернативы нетерминала . Например, если - все правила из и альтернативы упорядочены так, как записаны, то индексы их соответственно примут вид ;
2. Введем понятие конфигурации алгоритма – это упорядоченная четверка вида , где - состояние алгоритма, - номер позиции указателя чтения входной цепочки (предполагается, что -м входным символом является специальный символ (маркер) , означающий конец входной строки), - содержимое первого магазина, - содержимое второго магазина;
Примечание: Будем считать, что верх первого магазина расположен справа, а верх второго слева. Магазин служит для представления «текущей» левовыводимой цепочки, т.е. той, которая получилась к данному моменту в результате развертки нетерминалов. Другими словами, верхний символ магазина будет символом, помечающим активную вершину порожденного к данному моменту дерева вывода. В магазине представлены текущая история проделанных выборов альтернатив и выходные символы, по которым прошла входная головка.
Алгоритм может находиться в одном из трех состояний , где - состояние нормальной деятельности, - состояние возврата, - заключительное состояние.
3. Начальная конфигурация алгоритма - ;
4. Существует всего 6 типов шагов. Шаги будем описывать в терминах их воздействия на конфигурацию алгоритма. Запись вида означает переход из одной конфигурации алгоритма в другую . Число , если не оговорено обратное, , где - множество индексов альтернатив, .
а) Разрастание дерева
,
где и - первая альтернатива нетерминала .
Этот шаг соответствует разрастанию частичного дерева вывода, при котором применяется первая альтернатива самого левого нетерминала дерева;
б) Успешное сравнение входного символа с порожденным символом
при условии, что . Если -й входной символ совпадает с очередным порожденным терминальным символом, то он передается из в , а позиция входного указателя увеличивается на единицу;
в) Успешное завершение
.
Достигнут конец входной цепочки и найдена левовыводимая цепочка, совпадающая с входной. Левый разбор входной цепочки восстанавливается по цепочке с помощью гомоморфизма , что , , где - номер правила и - -ая альтернатива нетерминала ;
г) Неудачное сравнение входного символа с порожденным символом
Переходим в состояние возврата, как только обнаруживается, что порожденная левовыводимая цепочка не совместима с входной цепочкой;
д) Возврат по входу
для всех , т.е в состоянии возврата входные символы переносятся назад из в ;
е) Испытание очередной альтернативы
i. , если - -я альтернатива нетерминала (Заметим, что в заменяется на );
ii. Следующая конфигурация невозможна, если и имеет только альтернатив. (Это условие указывает на то, что всевозможные цепочки, совместимые с входной цепочкой уже исчерпаны, а ее разбор не найден);
iii. в оставшихся случаях. (Здесь исчерпаны альтернативы нетерминала и дальнейший возврат происходит путем удаления из и замены в цепочки на ).
Алгоритм выполняем следующим образом
Шаг 1. Исходя из начальной конфигурации, вычислять последующие конфигурации , пока их можно вычислить;
Шаг 2. Если последняя вычисленная конфигурация - , то выдать и остановиться, в противном случае – «ошибка»;
Пример :
Пусть задана КС-грамматика вида
.
Требуется построить левый разбор для цепочек вида
, , .
Решение:
1. Сделаем приведение грамматики, т.е. удалим пустые и цепные правила
2. Перенумеруем правила грамматики
;
Определяем левый разбор как последовательность вида
;
;
Определяем левый разбор как последовательность вида
;
;
.