- •Московский автомобильно-дорожный государственный технический университет (мади)
- •I.Формальные языки и грамматики
- •I.1. Цепочки символов
- •I.2. Операции над цепочками символов
- •I.3. Понятие языка
- •I.4. Способы задания языка
- •I.5. Синтаксис и семантика языка
- •I.6. Определение грамматики
- •I.7. Пример грамматики
- •I.8. Принцип рекурсии в правилах грамматики
- •I.9. Способы задания грамматик
- •I.9.1. Использование метасимволов
- •I.9.2. Запись правил грамматики в графическом виде
- •I.10. Распознаватель
- •I.10.1. Схема распознавателя
- •I.10.2. Задача разбора
- •I.11. Классификация грамматик
- •I.12. Классификация языков
- •I.13. Примеры классификаций языков и грамматик
- •I.14. Цепочки вывода
- •I.14.1. Понятие о выводе
- •I.14.2. Сентенциальная форма грамматики
- •I.14.3. Левосторонние и правосторонние выводы
- •I.14.4. Дерево вывода и методы его построения
- •I.15. Однозначности и эквивалентности грамматик
- •I.15.1. Однозначные и неоднозначные грамматики
- •I.15.2. Проверка однозначной и эквивалентной грамматик
- •I.15.3. Правила, задающие неоднозначность в грамматиках
- •II. Принципы построения трансляторов
- •II.1. Определения транслятора
- •II.2. Определение компилятора
- •II.3. Определения интерпретатора
- •II.4. Этапы трансляции
- •II.5. Фазы компиляции
- •II.6. Ти ( таблицы идентификаторов)
- •II.6.1. Назначение и особенности построения
- •II.6.2. Простейшие методы
- •II.6.3. Построение ти по методу бинарного дерева
- •II.6.5. Выбор Хэш-функции при построении ти
- •II.6.7. Построение ти по методу цепочек
- •II.7. Лексические анализаторы
- •II.7.1. Назначение ла
- •II.7.2. Определение границ лексем
- •II.7.3. Выполнение действий, связанных с лексемами
- •II.7.4. Применение конечных автоматов (ка) для построения ла
- •II.7.5. Алгоритм построения ка
- •II.7.6. Пример применения ка для построения ла
- •II.8. Принципы построения синтаксических анализаторов (са)
- •II.8.1. Значение са
- •II.8.2. Автоматы с магазинной памятью
- •II.9. Принципы построения семантического анализатора (с-а)
- •II.9.1. Назначение с-а
- •II.9.2. Проверка соблюдения во входной программе семантических соглашений
- •II.9.3. Дополнение внутреннего представления программы
- •II.9.4. Проверка смысловых норм языка программирования
- •II.10. Принципы генерации кода
- •II.11. Оптимизация кода
II.6.3. Построение ти по методу бинарного дерева
Можно сократить время поиска искомого элемента, не увеличивая значительно время, необходимое на заполнение ТИ, отказавшись от организации таблицы в виде непрерывного массива данных. Применяют метод построения таблиц, при котором они имеют форму бинарного дерева. Узел дерева – это элемент таблицы. Первый элемент является корневым узлом, встреченным при заполнении таблицы. Каждая вершина имеет не более двух ветвей. Применяются алгоритмы заполнения бинарного дерева. Он работает с потоком входных данных, содержащим идентификаторы (в компиляторе порождается в процессе разбора текста исходной программы). Поиск нужного элемента в дереве также выполняется по алгоритму, схожему алгоритму заполнения дерева.Бывает ситуация, когда при какой-либо последовательности дерево вырождается в упорядочный связной список. Это недостаток данного метода. Другой недостаток – необходимость работы с динамич. выделением дерева механической памяти. Среднее время на заполнение ТЗ и на поиск элемента в нем Тn определяется так
ТЗ = N * log2N
Этот метод нашел применение в ряде компиляторов.
II.6.4. ХЭШ-функции, ХЭШ-адресации
В реальных исходных программах количество идентификаторов столь велико, что логарифмическую зависимость их поиска от их числа не дают удовлетворительных результатов. Лучших результатов достигают методы с использованием хэш-функций и хэш-адресации.
Хэш-функцией – это некоторое отображение множества входных элементов R на множество целых неотрицательных чисел Z. Записывается так:
Z: F(r) = n, rR, nZ.
Множество допустимых входных R называется допустимыми значениями хэш-ф. Множество значений Хэш-ф называют подмножество M из множества целых неотрицательных чисел Z
Z: M Z
содерж. все функции, возвращ. Fф. Процесс отображения области опред. хеш-ф. на множество значений называется хэшированием. При работе с ТИ хэш-функция должна выполнять отображение имен идентификаторов на множество целых неотрицательных чисел. Областью определения хэш-функций будет множество всех возможных имен идентификаторов.
Хэш-адресация заключается в использовании значения, возвращаемого хэш-функцией, в качестве адреса ячейки из некоторого массива данных. Тогда размер его должен соответствовать области значений используемой хэш-функций. Тогда в реальном компиляторе область значений хэш-функций не должна превышать размер доступного адресного пространства. Метод организации ТИ, основанный на использовании
хэш-адресации, заключается в размещении каждого элемента таблицы в ячейке, адрес которой возвращает хэш-функция, вычисленная для этого элемента. Тогда в для размещения любого элемента достаточно вычислить его хэш-функцию и обратиться к нужной ячейке массива данных. Первоначально ТИ должна быть заполнена информацией о том, что все ее ячейки являются пустыми.
На рисунке проиллюстрирована организация ТИ с использованием хэш-адресации.
Трем различным идентификаторам A1, А2, А3 соответствуют три значения хэш-функций n1, n2, n3,которые адресуют ячейки, где содержится информация об этих идентификаторах. При поиске идентификатора вычисляется значение n и по этому адресу выбираются данные из соответствующей ячейки. Метод достаточно эффективен, т.к. время размещения элемента в таблице и время его поиска определяются только временем, затрачиваемым на определение хэш-функций, которое значительно меньше времени, необходимого на многократные сравнения элементов таблицы.
Недостатки: неэффективное использование объема памяти под таблицу идентификаторов, т.к. размер массива для ее хранения должен соответствовать области значений хэш-функции, в то время как для реально хранимых в таблице идентификаторов может быть существенно меньше. Второй недостаток — необходимость соответствующего разумного выбора хэш-функции.
