Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Шпоры по тяпу.docx
Скачиваний:
8
Добавлен:
01.04.2025
Размер:
808 Кб
Скачать
☆

14. Построение таблицы разбора для ll(1) – грамматики

Таблица синтаксического разбора представляет собой двумерную таблицу, в которой строки соответствуют нетерминалам, а столбцы – терминалам грамматики. Значения в ячейках этой таблицы определяют продукцию, которая должна быть активирована на текущем шаге алгоритма при получении следующей лексемы. Для построения данной таблицы требуется предварительно построить для каждого нетеминала грамматики множества first и follow. Эта таблица определяет, какую продукцию нужно рассматривать для некоторой пары: терминал на входе и нетерминал в вершине стека. Таблица разбора строится следующим образом.

Для всех продукций А грамматики выполняем:

1 Для всех терминалов а, принадлежащих first() в клетку [А, а] таблицы разбора записываем продукцию А.

2 Если  принадлежит first(), то для всех b, принадлежащих follow(А), в клетку [A, b] записываем продукцию А.

Во все остальные клетки таблицы записываем признак ошибки. Это означает, что при данном нетерминале в стеке не ожидается указанный терминал во входной последовательности.

Если при построении таблицы возникает попытка в одну клетку записать две или более продукции, то разбираемая грамматика не является LL(1)-грамматикой, следовательно, не может разбираться таким способом.

15. Алгоритм работы таблично управляемого анализатора для ll(1) – грамматики.

Состояние синтаксического анализатора можно сохранять в специальном стеке, и тогда можно уйти от рекурсии. А процедуру разбора можно сделать универсальной и управляемой таблично. Алгоритм разбора будет один и тот же, но его поведение будет определяться таблицей разбора.

Таблица разбора определяет для каждой пары (А,а), где А-нетерминал, а а-терминал продукцию или признак ошибки.

Алгоритм работы таблично управляемого синтаксического анализатора представлен ниже.

Занести символ окончания входной последовательности в стек

Занести в стек стартовый нетерминал

Распознать символ входной последовательности

Повторять

Если

в вершине стека находится терминал

то

Если

распознанный символа равен вершине стека

то

Извлечь из стека верхний элемент и распознать символ входной последовательности

иначе

вывести сообщение об ошибке;

иначе {если в вершине стека нетерминал}

Если

в клетке[вершина стека, распознанный символ] таблицы разбора существует правило

то

извлечь из стека элемент и занести в стек все терминалы и нетерминалы найденного в таблице правила в стек в порядке обратном порядку их следования в правиле

иначе

вывести сообщение об ошибке

пока

вершина стека не равна концу входной последовательности

Если

распознанный символ не равен концу входной последовательности

то

вывести сообщение об ошибке

Далее строится таблица разбора, а в те ячейки, которые оказались незаполненными, заносится признак ошибки. Построение таблицы станет невозможным при попытке вставить в одну и ту же ячейку два правила. Это значит, что используемая грамматика не относится к классу LL(1)-грамматик.

16. Грамматики простого предшествования. Использование отношения предшествования операторов

Грамматики простого предшествования отличаются следующим:

1) у них нет продукций, имеющих в правой части .

2) нет продукций, в которых два нетерминала стоят рядом.

Грамматики, удовлетворяющие второму требованию, называются операторными.

Например: E → EAE | (E )| -E | id

A → + | - | * | / | ^

можно преобразовать к операторному виду:

E → E+E | E-E | E*E | E/E | E^E | (E) | -E | id

Для нее на основе предшествующих операций можно строить дерево разбора. Для этого необходимо задать три отношения предшествования; на их основе можно выделить основы:

a ⋖ b - a уступает b

a ≐ b - a имеет одинаковый приоритет с b

a ⋗ b - a имеет приоритет над b

Эти операции имеют значение, отличное от арифметических, например, истинно a ⋖ b и b ⋖ a. Для некоторых нетерминалов могут вообще не выполняться такие операции. Отношение предшествования можно задать в форме таблицы, при помощи которой можно легко находить основы

id+id+id: $<• id•>+<•id•>*<•id•>$

Основы получаются: цепочка просматривается до знака •> метка идем обратно до знака <• метка. Между метками будет основа. Когда свернем эти основы, получим: Е+Е*Е. Нетерминалы нужны только для генерации результирующего кода.

Получим последовательность: + *.

 

id

+

*

$

id

 

⋗

⋗

⋗

+

⋖

⋗

⋖

⋗

*

⋖

⋗

⋗

⋗

$

⋖

⋖

⋖