
- •Содержание
- •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 Формирование ат-грамматики
- •Решение
5.3 Атрибутные транслирующие грамматики
5.3.1 Синтезируемые и наследуемые атрибуты
Каждому символу формальной грамматики присущи класс и значение. Скажем, если символом Е обозначено арифметическое выражение, то с ним может быть связано числовое значение, адрес памяти для числа, тип числа, признак обнаруженной в выражении ошибки и т.д. Все это значения символа Е. Рассмотренный ранее формализм перевода описывает перевод только той составляющей символа, которая характеризует его класс. Дальнейшее развитие теории компиляции касается значений символов.
Найти значение строки КС-языка можно, вычислив так называемые атрибуты в каждом узле дерева ее разбора. Атрибуты вычисляют по формулам, связанным с правилами грамматики языка. Атрибуты подразделяют на синтезируемые и наследуемые.
Синтезируемые атрибуты в некотором узле дерева зависят только от атрибутов в узлах-потомках. Значит, они служат для передачи информации по дереву снизу вверх, а в правилах грамматики — из правой части в левую.
Наследуемые атрибуты в некотором узле являются функциями атрибутов его узла-предка и (или) узлов-потомков этого предка. Такие атрибуты, как видим, могут распространять информацию в противоположном направлении.
Важно отметить, что КС-грамматика, снабженная атрибутами, сохраняет свои обычнее свойства и вместе с тем позволяет формально учесть контекстно-зависимые условия языка. А элементы контекстной зависимости присутствуют во всех языках программирования.
Рассмотрим суть синтезируемых атрибутов на примере, в котором синтаксический анализатор арифметических выражений выдает численное значение выражения. В этом простом примере операндами могут быть только константы. Т-грамматика выражений содержит единственный операционный символ (обозначим его [ЗНАЧ]) и имеет вид:
1) S ->Е[ЗНАЧ] 2)Е->Е+Т 3)E->T $)T->T*F 5) T->F
6) F->(E) 7) F->C
где VN = {S, E, T, F},
VT = {+, *, (,), С},
S — аксиома;
С — константа, значение которой во внутреннем представлении построил лексический анализатор.
Возьмем строку (С3 + С9)*С2 в качестве входной для синтаксического анализатора. В этом выражении подстрочными индексами указаны значения констант, которые и будем считать их атрибутами. Построим дерево разбора активной цепочки (C3+ С9)*С2[ЗНАЧ]24 и снабдим нетерминалы (в узлах дерева) значениями синтезируемых атрибутов (рис. 5.3 а).
Значение выражения формируется из значений его подвыражений по правилам (формулам), соответствующим правилам грамматики. Представим эти формулы математически, для чего в каждом правиле грамматики предусмотрим различные имена для разных значений атрибутов, а затем запишем соответствующие формулы. Атрибутом снабжается каждый нетерминал правила грамматики. Имена атрибутов обычно записывают как подстрочные индексы. Например, правилу Е —> Е+ Т транслирующей грамматики соответствуют правило Ер —> Eq+Tr и формула р=- q + r. Обозначения атрибутов в различных правилах не имеют между собой ничего общего и могут быть одинаковыми.
Рисунок 5.3 - а) Дерево разбора активной цепочки (С3+С9)*С2[ЗНАЧ]24
б) АТ-грамматика арифметических выражений
Полученные таким образом правила называют атрибутными, а грамматику с атрибутными правилами и формулами для атрибутов — атрибутной транслирующей грамматикой (АТ-грамматикой). Атрибутная транслирующая грамматика для нашего примера дана на рис. 5.3 б. Заметим, что атрибут операционного символа [ЗНАЧ] не относится к числу синтезируемых, он — наследуемый.
Теперь поясним смысл наследуемых атрибутов на примере, в котором синтаксический анализатор описания переменных помещает признак типа (real, int или boot) имени в соответствующее поле таблицы имен.
Пусть Т-грамматика описания переменных имеет вид:
описание —> Т V [тип] список
список —>, V [тип] список
список —>
В
этой грамматике символы "описание",
"список*' —
нетерминалы(
VN);
Т, V,,
— терминалы (VT),
[тип]
— операционный символ, где V
—
символ класса имен со значением,
представленным
указателем на элемент таблицы имен; Т—
символ класса ключевых
слов со значением, представленным
указателем на real,
int
или
bool.
Запятая
(,) — символ класса ограничителей.
Операционный
символ [тип]
располагается
в правилах вслед за именем V
и
предписывает поместить признак типа Т
в
поле "тип" записи переменной
V
таблицы
имен. Поэтому значение [тип]
определяется
парой атрибутов (указ,
тип), где
"указ"
—
указатель на запись
V
в
таблице имен, "тип"
—
значение Т.
Введем атрибуты и формулы для их вычисления в грамматику описания переменных. Будем использовать имена ti, где i = 0, 1, 2,..., для обозначения атрибута "тип" (значение Т), именами pi обозначим атрибут "указатель" (значение V). Для передачи типа переменной из правила 1 в последующие снабдим нетерминал "список" атрибутом типа. Тогда АТ-грамматика описания переменных может выглядеть так:
1) описание —> Tr0 Vp0 [тип]р1,r1 список t2
t2,t1 = t0;p1 =p0
2) cnucoкr0 -> , Vp0 [min]p1,t1 списокt2
t2,t1 = t0; р1 =р0
3)списокr0
->
Формула t2, t1 = t0 означает, что атрибуты t2 и t1 получают значение атрибута t0. Согласно формуле р1 = р1 атрибут р1 получит значение атрибута р0.
Возьмем в качестве примера описание real a, c1, abc. Синтаксический анализатор получит входную строку, которая в наших обозначениях выглядит так: Treal V1, V2 V3. Здесь 1, 2, 3 — номера позиций имен в таблице имен. Построим дерево разбора (рис. 5.1.4) соответствующей активной цепочки
Рисунок 5.4 - Дерево разбора активной цепочки
Как видно из рассмотренных примеров, информация о синтезируемых атрибутах распространяется вверх по дереву (см. рис. 5.3), а информация о наследуемых — вниз по дереву (рис. 5.4).