Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
СПО Часть 1.docx
Скачиваний:
25
Добавлен:
25.04.2019
Размер:
133.36 Кб
Скачать
  1. Синтаксический анализ: назначение, основные операции

Синтаксический анализатор – часть компилятора, которая отвечает за выявление основных синтаксических конструкций входного языка.

Задачи синтаксического анализатора:

  • выделение основных синтаксических конструкций в тексте исходной программы

  • определение типа синтаксической конструкции

  • проверка правильности синтаксической конструкции

  • представление синтаксической конструкции в виде, удобном для дальнейшей обработки компилятором

  • разбор арифметических и логических выражений

Синтаксический анализ цепочки некоторого языка представляет собой построение на основе продукций конкретной грамматики дерева разбора, которое характеризуется следующими условиями:

  • каждая вершина дерева обозначается символом грамматики А  (VN  VT);

  • корень дерева – вершина, обозначенная целевым символом S;

  • листья дерева (концевые вершины) – вершины, представляющие терминальные символы или пустую цепочку ;

  • если некоторая вершина (узел) дерева представляет А  VN, а связанные с ним узлы – символами b1, b2, …, bn, (n > 0), где bi  (VN  VT  {}), i=1..n, то в грамматике G для данного дерева существует правила вида

(А  b1, b2, …, bn)  Р.

Дерево вывода строится или сверху вниз, или снизу вверх.

Процедура построения дерева сверху вниз:

  1. Корень дерева – целевой символ S;

  2. Выбор подходящего правила и раскрытие символа на несколько символов первого уровня;

  3. Выбирается крайняя нетерминальная вершина (для левостороннего вывода – левая, для правостороннего – правая) и она с помощью соответствующего правила раскрывается на несколько вершин следующего уровня:

  4. Процесс заканчивается, когда все вершины будут представлять терминальные символы грамматики.

Построение дерева заканчивается, когда все концевые вершины представлены терминальными символами. Если данное условие выполнить не удается, то предложение является синтаксически не корректным. При этом надо помнить, что в реальных компиляторах в качестве терминальных символов рассматриваются коды лексем.

При движении снизу вверх строительство начинается с листьев дерева в виде терминальных символов. Построение идет по слоям путем выбора подходящих правил вывода. Естественно, движение ведется слева направо при левостороннем выводе и справа налево при правостороннем выводе.

  1. Таблицы лексем: варианты формирования

Первой фазой компиляции является лексический анализ (сканирование). Его суть – разделение текста программы на отдельные языковые конструкции – лексемы. Лексема является аналогом слова в естественном языке. Каждая лексема имеет свое смысловое значение, т.е. обладает семантикой. Лексемы являются листьями (конечными вершинами) дерева разбора программы. В это же время строится таблица лексем (идентификаторов). В ней все лексемы, имеющие разную длину, заменяются кодами одинаковой длины, т.е. исходный листинг заменяется текстом на некотором промежуточном языке, что упрощает последующие фазы компиляции. В эту же таблицу могут заноситься и типы переменных программы. Во время данной фазы удаляются из программы пробелы и комментарии, а также фиксируются лексические ошибки (недопустимые символы, неправильные идентификаторы).

На выходе лексического сканера обычно представлены две таблицы: одна включает перечень заранее определенных лексем с их предопределенными кодами, а вторая формируется из определяемых в процессе компиляции лексем.

В таблицах указываются свойства лексем, причем для разных лексем они разны. В таблице стандартных лексем, существующих исходно, для арифметических и логических операторов указывается старшинство операций. Оно требуется для построения синтаксического дерева, т.е. данная таблица может иметь такой вид:

Символ операции

Код

Класс символа

Старшинство

Для функций указывается имя, количество и типы формальных аргументов, тип возвращаемого результата и т.д. Для массива нужно указать количество элементов и тип элемента, поскольку это понадобится в дальнейшем при выделении памяти.

Возможны варианты, когда отдельно формируются таблица идентификаторов и таблица литералов (целых, вещественных чисел и т.п.).

При этом решается весьма важная проблема – порядок размещение в таблице лексем, поскольку время работы с таблицей характеризует качество транслятора. К настоящему времени известно несколько вариантов формирования таких таблиц. Наиболее простыми являются:

В порядке поступления

Очередная лексема добавляется в конец таблицы, т.е. таблица не упорядочена. Добавление в таблицу реализуется весьма просто, но поиск требует, в общем случае, последовательного (линейного) просмотра всей таблицы, т.е. время поиска в общем случае при числе элементов таблицы N пропорционально tп ~ N/2.

Время записи tз не зависит от числа элементов таблицы.

При большом числе лексем такой метод организации таблиц является неэффективным, поскольку таблицы чаще просматриваются, чем дополняются.

Сортировка таблицы

Все лексемы сортируются в алфавитном порядке. Поиск в этом случае более эффективен, поскольку он реализуется по бинарному или логарифмическому алгоритмы. Для таблицы длиной N

tп ~ 1 + log2(N).

Таблица в виде двоичного дерева

tп ~ log2(N)

Алгоритм построения двоичного дерева:

Хеш-функция – это отображение множества водных элементов на множество целых неотрицательных чисел.

Хеширование:

  1. Выделяется лексема

  2. Вычисляется хеш-функция

  3. Идет обращение к ячейку по адресу, полученному в результате хеширования

  4. Если ячейка пустая, то в нее заносится лексема. Если ячейка не пуста, то лексема занесена ранее.

Алгоритм эффективного хеширования:

  1. Вычисляется хеш-адрес встреченной лексемы (код*10)

  2. Идет обращение по этому адресу

  3. Если ячейка пуста, то в нее заносится лексема. Если ячейка занята, то ее содержание сравнивается с текущей лексемой

  4. Если имеют место совпадения, то лексема уже занесена, конец алгоритма. Если результат сравнения отрицательный, то переход к следующей ячейке и возврат к п. 3.

Коэффициент Lf – load factor

(количество лексем на количество слов)