- •Содержание
- •1 Формальные языки и грамматики
- •1.1 Основные понятия теории формальных языков
- •Определение Цепочка, которая не содержит ни одного символа, называется пустой цепочкой и обозначается .
- •1.2 Способы задания языков
- •1.2.1 Формальные грамматики
- •1.2.1.1 Определение формальной грамматики
- •Определение Цепочка (vtvn)* выводима из цепочки в грамматике(обозначается*), если существует последовательность цепочек (n0) такая, что .
- •1.2.1.3 Эквивалентность грамматик
- •1.2.2 Формы Бэкуса - Наура
- •1.2.3 Диаграммы Вирта
- •1.2.5 Механизмы распознавания языков
- •1.2.5.1 Определение распознавателя
- •1.2.5.2 Схема работы распознавателя
- •1.2.5.3 Классификация распознавателей
- •2 Регулярные грамматики и языки
- •2.1 Регулярные выражения
- •2.2 Лемма о разрастании языка
- •2.3 Конечные автоматы
- •2.3.1 Определение конечного автомата
- •2.3.2 Распознавание строк конечным автоматом
- •Существуют следующие способы представления функции переходов: - командный способ.Каждую команду ка записывают в форме , где.
- •2.3.3 Преобразование конечных автоматов
- •2.3.3.1 Преобразование конечного автомата к детерминированному виду
- •Алгоритм Преобразование нка в дка
- •2.3.3.2 Минимизация конечного автомата
- •2.3.3.2.1 Устранение недостижимых состояний ка
- •2.3.3.2.2 Объединение эквивалентных состояний ка Алгоритм Объединение эквивалентных состояний ка
- •2.4 Взаимосвязь способов определения грамматик
- •2.4.1 Построение ка по регулярной грамматике
- •Выход:ка.
- •3 Контекстно-свободные языки и грамматики
- •3.1 Задача разбора
- •3.1.1 Вывод цепочек
- •Определение Цепочка (vtvn)* выводима из цепочки в грамматике(обозначается*), если существует последовательность цепочек (n0) такая, что .
- •3.1.2 Дерево разбора
- •3.1.2.1 Нисходящее дерево разбора
- •3.1.2.2 Восходящее дерево разбора
- •3.1.3 Однозначность грамматик
- •3.2 Преобразование кс-грамматик
- •3.2.1 Проверка существования языка грамматики
- •3.2.2 Устранение недостижимых символов
- •Алгоритм Устранение нетерминалов, не порождающих терминальных строк Вход: кс-грамматика.
- •Алгоритм Устранение недостижимых символов Вход: кс-грамматика.
- •Определим множество достижимых символов z грамматики g, т.Е. Множество
- •3.2.3 Устранение -правил Алгоритм Устранение -правил Вход: кс-грамматика.
- •3.2.4 Устранение цепных правил Алгоритм Устранение цепных правил Вход: кс-грамматика.
- •3.2.5 Левая факторизация правил Алгоритм Устранение левой факторизации правил Вход: кс-грамматика.
- •3.2.6 Устранение прямой левой рекурсии Алгоритм Устранение прямой левой рекурсии Вход: кс-грамматика.
- •3.3 Автомат с магазинной памятью
- •3.3.1 Определение мп-автомата
- •3.3.2 Разновидности мп-автоматов
- •3.3.3 Взаимосвязь мп-автоматов и кс-грамматик
- •3.3.3.1 Построение мп-автомата по кс-грамматике
- •3.3.3.2 Построение расширенного мп-автомата по кс-грамматике
- •3.4 Нисходящие распознаватели языков
- •3.4.1 Рекурсивный спуск
- •3.4.1.1 Сущность метода
- •3.4.1.2 Достаточные условия применимости метода рекурсивного спуска
- •3.4.2 Распознаватели ll(k)-грамматик
- •3.4.2.1 Определение ll(k)-грамматики
- •3.4.2.2 Необходимое и достаточное условие ll(1)-грамматики
- •3.4.2.3 Построение множества first(1, a)
- •3.4.2.4 Построение множества follow(1, a)
- •3.4.2.5 Алгоритм «сдвиг-свертка» для ll(1)-грамматик
- •Шаг 6. Получили следующую цепочку вывода:
- •3.5.1.1.2 Поиск основы сентенции грамматики
- •3.5.1.1.3 Построение множеств l(a) и r(a)
- •3.5.1.1.5 Алгоритм «сдвиг - свертка» для грамматик простого предшествования
- •Шаг 3. Функционирование распознавателя для цепочки (((aa)a)a) показано в таблице 3.9.
- •3.5.1.2 Грамматика операторного предшествования
- •3.5.1.2.1 Определение грамматики операторного предшествования
- •3.5.1.2.2 Построение множеств Lt(a) и Rt(a)
- •3.5.1.2.4 Алгоритм «сдвиг-свертка» для грамматики операторного предшествования
- •3.5.2 Распознаватели lr(k)-грамматик
- •3.6 Соотношение классов кс-грамматик и кс-языков
- •3.6.1 Соотношение классов кс-грамматик
- •3.6.2 Соотношение классов кс-языков
- •4 Принципы построения языка
- •4.1 Лексика, синтаксис и семантика языка
- •4.2 Определение транслятора, компилятора, интерпретатора и ассемблера.
- •4.3 Общая схема работы компилятора
- •4.4 Лексический анализ
- •4.4.1 Задачи лексического анализа
- •4.4.2 Диаграмма состояний с действиями
- •4.4.3 Функция scanner
- •4.5 Синтаксический анализатор программы
- •4.5.1 Задача синтаксического анализатора
- •4.5.2 Нисходящий синтаксический анализ
- •Теорема Достаточные условия применимости метода рекурсивного спуска
- •4.6 Семантический анализ программы
- •4.6.1 Обработка описаний
- •4.6.2 Анализ выражений
- •4.6.3 Проверка правильности операторов
- •4.7 Генерация кода
- •4.7.1 Формы внутреннего представления программы
- •4.7.1.1 Тетрады
- •4.7.1.2 Триады
- •4.7.1.3 Синтаксические деревья
- •4.7.1.4 Польская инверсная запись
- •Составной оператор begin s1; s2;...; Sn end в полиЗе записывается как s1 s2... Sn.
- •4.7.1.5 Ассемблерный код и машинные команды
- •4.7.2 Преобразование дерева операций в код на языке ассемблера
- •4.8 Оптимизация кода
- •4.8.1 Сущность оптимизации кода
- •4.8.2 Критерии эффективности результирующей программы
- •4.8.3 Методы оптимизации кода
- •4.8.4 Оптимизация линейных участков программ
- •4.8.4.1 Свертка объектного кода
- •4.8.4.2 Исключение лишних операций
- •4.8.5 Оптимизация логических выражений
- •4.8.6 Оптимизация циклов
- •4.8.7 Оптимизация вызовов процедур и функций
- •4.8.9 Машинно-зависимые методы оптимизации
- •4.8.9.1 Распределение регистров процессора
- •4.8.9.2 Оптимизация кода для процессоров, допускающих распараллеливание вычислений
- •5 Формальные методы описания перевода
- •5.1 Синтаксически управляемый перевод
- •5.1.1 Схемы компиляции
- •5.1.4 Практическое применение су-схем
- •5.2 Транслирующие грамматики
- •5.2.1 Понятие т-грамматики
- •5.3 Атрибутные транслирующие грамматики
- •5.3.1 Синтезируемые и наследуемые атрибуты
- •5.3.2 Определение и свойства ат-грамматики
- •5.3.3 Формирование ат-грамматики
- •Решение
Шаг 3. Функционирование распознавателя для цепочки (((aa)a)a) показано в таблице 3.9.
Таблица 3.9 – Алгоритм работы распознавателя цепочки (((aa)a)a)
Шаг |
Стек |
Входной буфер |
Действие | |
1 |
н |
(((aa)a)a)к |
сдвиг | |
2 |
н( |
((aa)a)a)к |
cдвиг | |
3 |
н(( |
(aa)a)a)к |
cдвиг | |
4 |
н((( |
aa)a)a)к |
cдвиг | |
5 |
н(((a |
a)a)a)к |
свертка Sa | |
6 |
н(((S |
a)a)a)к |
сдвиг | |
7 |
н(((Sa |
)a)a)к |
сдвиг | |
8 |
н(((Sa) |
a)a)к |
свертка RSa) | |
9 |
н(((R |
a)a)к |
свертка S(R | |
10 |
н((S |
a)a)к |
сдвиг | |
11 |
н((Sa |
)a)к |
сдвиг | |
12 |
н((Sa) |
a)к |
свертка RSa) | |
13 |
н((R |
a)к |
свертка S(R | |
14 |
н(S |
a)к |
сдвиг | |
15 |
н(Sa |
)к |
сдвиг | |
16 |
н(Sa) |
к |
свертка RSa) | |
17 |
н(R |
к |
свертка S(R | |
18 |
нS |
к |
строка принята |
Шаг 4. Получили следующую цепочку вывода:
S(R(Sa)((Ra)((Sa)a)(((Ra)a)(((Sa)a)a)(((aa)a)a).
Восходящее дерево вывода цепочки представлено на рисунке 3.5.2
Рисунок 3.5 – Дерево вывода для цепочки (((aa)a)a)в грамматике G
3.5.1.2 Грамматика операторного предшествования
3.5.1.2.1 Определение грамматики операторного предшествования
Определение КС-грамматика G (VN, VT, P, S) называется грамматикой операторного предшествования, если выполняются следующие условия:
1) Для каждой упорядоченной пары терминальных символов выполняется не более чем одно из трех отношений предшествования:
а) а = b, если и только если существует правило A—>xaby Р или правило А->хаСbу, где a,bVT, A,C VN, x.yV*;
б) а < b, если и только если существует правило А->хаСу Р и вывод C=>*bz или вывод C=>*Dbz, где a,bVT, A,C,DVN, x,y,zV*;
в) а > b, если и только если существует правило А—>хСЬу Р и вывод C=>*za или вывод C=>*zaD, где a,bVT, A,C,DVN, x,y,zV*.
2) Различные правила в грамматике имеют разные правые части, -правила отсутствуют.
Правила грамматики операторного предшествования не могут содержать двух смежных нетерминальных символов в правой части, т.е. в грамматике операторного предшествования G(VN,VT,P,S) не может быть ни одного правила вида: А->хВСу, где A,B,CVN, x,yV* (здесь х и у — это произвольные цепочки символов, могут быть и пустыми).
3.5.1.2.2 Построение множеств Lt(a) и Rt(a)
Принцип работы распознавателя для грамматики операторного предшествования аналогичен грамматике простого предшествования, но отношения предшествования проверяются в процессе разбора только между терминальными символами.
Для грамматики данного вида на основе установленных отношений предшествования также строится матрица предшествования, но она содержит только терминальные символы грамматики.
Для построения этой матрицы удобно ввести множества крайних левых и крайних правых терминальных символов относительно нетерминального символа А – Lt(A) или Rt(A):
Lt(A) = {t | A=>*tz или A=>*Ctz }, где tVT, A.CVN, zV*;
Rt(A)= {t | A=>*zt или A=>*ztC }, где tVT, A,CVN, zV*.
Тогда определения отношений операторного предшествования будут выглядеть так:
а) а = b, если правило A→xaby Р или правило U->xaCby, где a,bVT, А,СVN х,уV*;
б) а < b, если правилоА→хаСу Р и b Lt (C), где a,bVT, A,CVN, x,yV*;
в) а > b, если правило A→xCby Р и a Rt(C), где a,bVT, A,CVN, x,yV*.
В данных определениях цепочки символов x,y,z могут быть и пустыми цепочками.
Для нахождения множеств Lt(A) и Rt(A)предварительно необходимо выполнить построение множеств L(A) и R(A), как это было рассмотрено ранее. Далее для построения Lt(A) и Rt(A) используется следующий алгоритм:
Шаг 1. AVN:
Rt0(A){t | A→ytB или A→yt, tVT, BVN, yV*;
Lt0(A){t | A→Bty или A→ty, tVT, BVN, yV*;
Для каждого нетерминального символа А ищем все правила, содержащие А в левой части. Во множество L(A) включаем самый левый терминальный символ из правой части правил, игнорируя нетерминальные символы, а во множество R(А) - самый крайний правый терминальный символ из правой части правил. Переходим к шагу 2.
Шаг 2. AVN:
Rti(A) = Rti-1(A) Rti-1 (B), В (R(A) VN),
Lti(А) = Lti-1(A) Lti-1(B), В (L(A) VN).
Для каждого нетерминального символа А: если множество L(A) содержит нетерминальные символы грамматики А', А", ..., то его надо дополнить символами входящими в соответствующие множества L t(А’), L t(A"), ... и не входящими в L t(А). Ту же операцию надо выполнить для множеств R(A) и Rt(А).
Шаг З. Если AVN : Rti(A) Rti-1(A или Lti(А) Lti-1(A), то i:=i+1 и вернутся к шагу 2, иначе построение закончено: Rt(A) = Rti(A) и Lt(A) = Lti(А).
Если на предыдущем шаге хотя бы одно множество Rt(A) или Lt(A) для некоторого символа грамматики изменилось, то надо вернуться к шагу 2, иначе построение закончено.
Для практического использования матрицу предшествования дополняют символами и( начало и конец цепочки). Для них определены следующие отношения предшествования:
<· a, aVT, если S=>*ax или S=>*Cax, где S,CVN, xV* или если a Lt(S);
·> а, aVT, если S=>*xa или S=>*xaC, где S,CVN, xV* или если a Rt(S).
Здесь S — целевой символ грамматики.
Матрица предшествования служит основой для работы распознавателя языка, заданного грамматикой операторного предшествования. Поскольку она содержит только терминальные символы, то, следовательно, будет иметь меньший размер, чем аналогичная матрица для грамматики простого предшествования. Следует отметить, что напрямую сравнивать матрицы двух грамматик нельзя — не всякая грамматика простого предшествования является грамматикой операторного предшествования, и наоборот.