Лексер + Парсер. Часть 2.
Этапы компиляции
Этапы фронтэнда
Схема работы
Схема работы
Схема работы
Строгие определения. Грамматики.
Классификация грамматик по Хомскому
Строгие определения. Типы грамматик.
Соответствие языков и грамматик
Способы разбора грамматик
Строгие определения. Конечные автоматы с магазинной памятью.
Варианты синтаксического анализа
Дерево разбора
Метод рекурсивного спуска
Метод рекурсивного спуска
Пример применения метода рекурсивного спуска
Рекурсивный спуск, минусы
Предиктивный анализатор
Предиктивный анализатор
Предиктивный анализатор
Предиктивный анализатор
Предиктивный анализатор
Предиктивный анализ
Предиктивный анализ
Предиктивный анализ
Предиктивный анализ, разбор
Предиктивный анализ, пример
Восходящий анализатор
Построение LR(1) анализатора
Пополнение грамматики
Каноническая система множеств
Пример
Построение Goto
Построение action
Пример
Восходящий анализ, разбор
Восходящий анализ, пример
Обрабатываемые ошибки
Должны быть ясны вопросы:
0.96M
Категория: ПрограммированиеПрограммирование

Лексер. Парсер. (Часть 2)

1. Лексер + Парсер. Часть 2.

Илья Филиппов
05.10.2015
1

2. Этапы компиляции

Фронтэнд
Машинно независимые оптимизации
Код генерация + машинно зависимые
оптимизации
2

3. Этапы фронтэнда

Лексический анализатор (лексер)
Синтаксический анализатор (парсер)
Семантический анализатор
Генерация промежуточного представления
3

4. Схема работы

Токен
Исходный
код
Лексер
Парсер
Следующий
Семантический
анализ
Символьная
таблица
4

5. Схема работы

Лексер формирует последовательности
входных символов в лексемы и отправляет
токены парсеру.
◦ Лексема – минимальная единица языка, имеющая
самостоятельный смысл.
◦ Токен – тип лексемы + аттрибут
Парсер формирует исходное выражение
языка, запрашивая токены.
5

6. Схема работы

Обрабатываемые лексером и парсером
последовательности символов и лексем
напрямую зависят от спецификации языка.
Необходим способ описания
◦ «что в языке может быть»
◦ «что в языке не может быть»
6

7. Строгие определения. Грамматики.

Алфавит – множество символов, используемых в языке
Терминальный символ - символ из алфавита
Нетерминальный символ – символ не из алфавита
Цепочка — последовательность символов
Терминальная цепочка – цепочка, состоящая из терминальных
символов
Язык – множество терминальных цепочек
Пример грамматики:
S->aQbZ
Q->ab | cc | Qd
Z -> aQa | c | ε
7

8. Классификация грамматик по Хомскому

Тип 0: неограниченные
Тип 1: контекстно-зависимые /
неукорачивающие
Тип 2: контекстно-свободные
Тип 3: регулярные:
праволинейные/леволинейные
8

9. Строгие определения. Типы грамматик.

Регулярные грамматики:
◦ праволинейные (A → w, A → wB, A,B ∈ N, w ∈ T*)
◦ леволинейные (A → w, A → Bw, A,B ∈ N, w ∈ T*)
Контекстно-свободные грамматики:
◦ (A → w, A ∈ N, w ∈ (T U N)*)
9

10. Соответствие языков и грамматик

Тип 0 (неограниченные): естественные
языки:
◦ Русский
◦ Английский
Тип 2 (контекстно-свободные):
большинство языков программирования:
◦ Java
◦ С++
Тип 3: (регулярные): описание отдельных
лексем в языках программирования:
◦ Идентификатор
◦ Числовая константа
10

11. Способы разбора грамматик

Тип 2 контекстно – свободная грамматика:
◦ может быть описана с помощью конечного
автомата с магазинной памятью
◦ Используется для анализа последовательности
токенов синтаксическим анализатором
Тип 3 регулярная грамматика:
◦ Может быть описана с помощью конечного
автомата
◦ Используется для формирования лексемы
лексическим анализатором
11

12. Строгие определения. Конечные автоматы с магазинной памятью.

Недетерминированный
Детерминированный
12

13. Варианты синтаксического анализа

Нисходящий анализ
◦ Метод рекурсивного спуска (парсер с возвратом)
◦ Предиктивный анализатор (предсказывающий
анализатор) (LL анализатор)
Восходящий анализ (LR анализатор)
13

14. Дерево разбора

id + id * id
14

15. Метод рекурсивного спуска

Дерево разбора строится сверху вниз, слева
направо
Токены от лексера рассматриваются в
порядке поступления
15

16. Метод рекурсивного спуска

Каждому нетерминалу соответствует
процедура, в которую жёстко зашиты
продукции данного нетерминала
Процедура последовательно сравнивает
пришедшие токены с терминалами
продукций
Если ни одна продукция не подходит –
ошибка
Если встречается нетерминал управление
переходит в процедуру нетерминала
16

17. Пример применения метода рекурсивного спуска

17

18. Рекурсивный спуск, минусы

Грамматика жёстко зашита в алгоритм. В
последующих алгоритмах на основании
грамматики строятся таблицы
Алгоритм выполняется за
экспоненциальное время
Алгоритм может зацикливаться
Использование неявного стека
18

19. Предиктивный анализатор

Идея – убрать откатывание. По каждому
символу должно быть изначально ясно куда
переходим.
Преобразование грамматики
◦ Удаление левой рекурсии
◦ Левая факторизация
Вычисление множеств
◦ FIRST
◦ FOLLOW
Составление таблицы
19

20. Предиктивный анализатор

Удаление левой рекурсии
Левая факторизация
20

21. Предиктивный анализатор

Пример преобразования
грамматики:
21

22. Предиктивный анализатор

Определение множества FIRST
◦ FIRST(a), a∈(N⋃T)* - множество терминалов или ℇ,
с которых может начинаться а.
Построение множества FIRST
22

23. Предиктивный анализатор

Определение множества FOLLOW
◦ FOLLOW(A), A∈N – множества терминалов,
которые могут появиться сразу за А, включая
концевой маркер $
Построение множества FOLLOW
23

24. Предиктивный анализ

Пример построения FIRST, FOLLOW
24

25. Предиктивный анализ

Построение таблицы
25

26. Предиктивный анализ

Пример построения таблицы
26

27. Предиктивный анализ, разбор

27

28. Предиктивный анализ, пример

28

29. Восходящий анализатор

Строим дерево разбора начиная с листьев
Для большинства языков программирования
можно построить LR грамматику
Наиболее общий метод анализа без отката
Существуют генераторы LR анализаторов
29

30. Построение LR(1) анализатора

1. Пополнение грамматики
2. Построение канонической системы
множеств допустимых LR(1)-ситуаций
3. Построение таблицы анализатора
◦ 3.1 Построение таблицы Goto
◦ 3.2 Построение таблицы Actions
4. Разбор цепочки

31. Пополнение грамматики

Добавим новое правило S' → S, и сделаем S'
аксиомой грамматики.
Допуск имеет место когда возможно
осуществить свёртку по правилу S → S'.

32. Каноническая система множеств

Вначале имеется множество I0 с
конфигурацией анализатора S' → .S, $
К этой конфигурации
применяется операция закрытия до тех
пор, пока в результате её применения не
перестанут добавляться новые
конфигурации.
Строятся переходы в новые множества
путём сдвига точки на один символ вправо

33. Пример

33

34. Построение Goto

Eсли в канонической системе множеств есть
переход из Ii в Ij по символу A, то в Goto(Ii,
A) мы ставим состояние Ij. После
заполнения таблицы полагаем, что во всех
пустых ячейках Goto(Ii, A) = Error
После заполнения таблицы полагаем, что
во всех пустых ячейках Goto(Ii, A) = Error

35. Построение action

Если есть переход по терминалу a из
состояния Ii в состояние Ij, то Action(Ii, a) =
Shift(Ij)
Если A ≠ S' и есть конфигруация A → α., a,
то Action(Ii, a) = Reduce(A → α)
Для состояния Ii, в котором есть
конфигурация S' → S., $, Action(Ii, $) =
Accept
Для всех пустых ячеек Action(Ii, a) = Error

36. Пример

36

37. Восходящий анализ, разбор

37

38. Восходящий анализ, пример

38

39. Обрабатываемые ошибки

Баланс скобок {…{…(…)…(((…))…)…}…(…}…}
Верность выражений “+” между expr
39

40. Должны быть ясны вопросы:

Место выполнения синтаксического
анализатора
Нисходящий анализ
◦ Метод рекурсивного спуска
◦ Предиктивный анализатор
Восходящий анализ
40
English     Русский Правила