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

10. Левая факторизация.

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

Например: S→ if B then S

│if B then S else S

Эти продукции нарушают условие LL(1)-грамматик. Эту грамматику можно преобразовать к виду LL(1).

S → if B then S Tail

Tail → else S

| ε

В общем виде это преобразование можно определить так:

A → α β1 | α β2 … | α βN | γ

вводим новый нетерминал В, для которого

A → α B | γ

B → β1 | β2 … | βN

Для B можно применить левую факторизацию. Эта процедура повторяется, пока остается неопределенным выбор продукции (т.е. пока в ней можно что-нибудь изменить).

12. Построение множества follow

Множество Follow для нетерминала определяет множество терминалов, которые могут следовать непосредственно за данным нетерминалом.

Алгоритм построения множества Follow выглядит следующим образом:

  1. Пусть goal – стартовый нетерминал. Тогда follow(goal) = {EOF}, где EOF – символ конца входной последовательности. Вначале символ конца входной последовательности помещается в множество follow стартового нетерминала

  2. Если есть правило A -> aBb, то follow(B) = follow(B) + first(b) - {ɛ}. То есть, если есть правило, утверждающее, что за В следует , то за нетеримналом будут следовать терминалы, с которых начинается последовательность .

  3. Если есть правило A -> aB, то в множество follow(B) = follow(B) + follow(A). То есть, если есть правило, утверждающее, что нетерминалом В заканчивается последовательность А, то за нетрминалом В будут следовать те же терминалы, что и за всей последовательностью А.

  4. Если есть продукция A -> aBb и {ɛ} принадлежит first(B), то follow(B) = follow(B) + follow(A).

  5. Если на шагах 2-4 множество follow было изменено, перейти к п.2

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

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

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

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

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

Повторять

Если

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

то Если

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

то

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

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

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

Если

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

то

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

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

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

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

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]