
- •2. Недетерминированный конечный автомат: формальное определение, построение множества достижимых состояний.
- •4. Преобразование недетерминированного конечного автомата в детерминированный.
- •6. Контекстно-свободные языки. Вывод. Дерево вывода.
- •8. Метод грамматического разбора сверху - вниз. Ll(1) – грамматики.
- •10. Левая факторизация.
- •12. Построение множества follow
- •14. Алгоритм работы таблично управляемого анализатора для ll(1) – грамматики.
- •32. Генератор компиляторов уасс. Использование неоднозначных грамматик.
- •18. Разбор методом «сдвиг – свертка» (shift – reduce) на основе стека.
- •24. Алгоритм заполнения таблиц разбора для slr (1) анализатора.
- •28. Построение абстрактного синтаксического дерева.
- •22. Каноническая совокупность множеств ситуаций.
- •34. Автомат с магазинной памятью. Допустимость по заключительному состоянию и по пустому магазину.
- •36. Lr(1) анализ. Lr(1)-ситуация. Замыкание множества ситуаций. Определение переходов.
- •16. Построение отношения предшествования операторов исходя из их ассоциативности и приоритета. Алгоритм разбора для грамматик простого предшествования.
- •38. Lalr(1) – грамматики. Построение lalr(1) – таблиц разбора.
- •1. Операции над языками. Регулярные выражения.
- •4) Положительное замыкание Клини (без пустой строки):
- •3. Преобразование регулярных выражений в недетерминированный конечный автомат
- •5. Минимизация детерминированного конечного автомата.
- •13. Построение таблицы разбора для ll(1) – грамматики
- •7. Контекстно-свободные грамматики для регулярных языков.
- •11. Построение множества first
- •9. Исключение левой рекурсии.
- •15. Грамматики простого предшествования. Использование отношения предшествования операторов
- •21. Алгоритм вычисления замыкания множества ситуаций (Closure).
- •17. Синтаксический анализ снизу – вверх. Основа. Подрезка основы.
- •19. Активный префикс. Обосновать, что основа всегда формируется в вершине стека.
- •27. Синтезируемые атрибуты. Их обработка в алгоритме сдвиг–свертка.
- •23. Переходы в slr (1) анализаторе. Функция goto. Допустимая ситуация.
- •29. Наследуемые атрибуты. Граф зависимостей.
- •25. Алгоритм lr – разбора.
- •33. Автомат с магазинной памятью. Графическое представление автомата с магазинной памятью. Вычислительный процесс в мп – автомате.
- •37. Lr(1) анализ. Заполнение таблиц lr-разбора
- •35. Типы и проверка типов.
- •26. Контекстно–зависимый анализ. Синтаксически управляемая трансляция.
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 выглядит следующим образом:
Пусть goal – стартовый нетерминал. Тогда follow(goal) = {EOF}, где EOF – символ конца входной последовательности. Вначале символ конца входной последовательности помещается в множество follow стартового нетерминала
Если есть правило A -> aBb, то follow(B) = follow(B) + first(b) - {ɛ}. То есть, если есть правило, утверждающее, что за В следует , то за нетеримналом будут следовать терминалы, с которых начинается последовательность .
Если есть правило A -> aB, то в множество follow(B) = follow(B) + follow(A). То есть, если есть правило, утверждающее, что нетерминалом В заканчивается последовательность А, то за нетрминалом В будут следовать те же терминалы, что и за всей последовательностью А.
Если есть продукция A -> aBb и {ɛ} принадлежит first(B), то follow(B) = follow(B) + follow(A).
Если на шагах 2-4 множество follow было изменено, перейти к п.2
14. Алгоритм работы таблично управляемого анализатора для ll(1) – грамматики.
Состояние синтаксического анализатора можно сохранять в специальном стеке, и тогда можно уйти от рекурсии. Алгоритм разбора будет определяться таблицей разбора, которая определяет для каждой пары (А,а), где А-нетерминал, а а-терминал продукцию или признак ошибки. Алгоритм:
Занести символ окончания входной последовательности в стек
Занести в стек стартовый нетерминал
Распознать символ входной последовательности
Повторять
Если
в вершине стека находится терминал
то Если
распознанный символа равен вершине стека
то
Извлечь из стека верхний элемент и распознать символ входной последовательности
иначе вывести сообщение об ошибке;
иначе {если в вершине стека нетерминал}
Если
в клетке[вершина стека, распознанный символ] таблицы разбора существует правило
то
извлечь из стека элемент и занести в стек все терминалы и нетерминалы найденного в таблице правила в стек в порядке обратном порядку их следования в правиле
иначе вывести сообщение об ошибке
пока вершина стека не равна концу входной последовательности
Если распознанный символ не равен концу входной последовательности
то вывести сообщение об ошибке. Далее строится таблица разбора, а в те ячейки, которые оказались незаполненными, заносится признак ошибки. Построение таблицы станет невозможным при попытке вставить в одну и ту же ячейку два правила. Это значит, что используемая грамматика не относится к классу LL(1)-грамматик.