Санкт-Петербургский государственный университет
Опубликован: 11.10.2012 | Доступ: свободный | Студентов: 956 / 174 | Длительность: 05:14:00
Лекция 9:

Компиляторы

Аннотация: В этой лекции даются основные факты о назначении компиляторов, их работе и возможностям автоматической оптимизации.

Презентацию к данной лекции Вы можете скачать здесь.

Компиляция - первый шаг в создании процесса

От исходного текста программы к процессу (Linux)


Транслятор выполняет преобразование программы, написанной на одном языке программирования в программу на другом языке программирования.

Компилятор выполняет преобразование программы, написанной на языке программирования (как правило, высокого уровня) в программу на языке машинного уровня.

Результат трансляции и компиляции должны быть эквивалентны исходным программам – прежде всего, должна сохраняться корректность алгоритма.

Основные фазы компиляции


Лексический анализ - включает распознавание лексем языка программирования, замену их соответствующими кодами.

Лексемы - элементарные единицы, наделенные определенным "смыслом" и входящие в структуру предложения языка (ключевые или зарезервированные слова, константы, имена и т.д.).

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

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

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

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

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

Лексический анализ

Функции лексического анализатора:

  • ввод строк исходной программы;
  • распознавание лексем;
  • заполнение таблиц идентификаторов и литералов;
  • печать листинга исходной программы.

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

Лексический анализатор использует:

  • исходный текст программы;
  • таблицу терминальных символов;
  • таблицу литералов;
  • таблицу идентификаторов.

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

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

Таблица литералов - таблица, содержащая литералы (константы), их тип и другую информацию. Литералу выделяется ячейка памяти, в которую записывается константа. Далее все появления этого литерала заменяются обращениями по адресу этой ячейки.

Результат работы сканера - последовательность кодов лексем. Код лексемы представляется кодом таблицы и спецификатором. Спецификатор задает номер строки в таблице, куда занесена лексема.

Синтаксический анализ

Синтаксис и семантика.

Синтаксис - множество правил, описывающих структуру предложений языка (порядок следования лексем). Речь идет о формальной структуре предложений, а не о смысле.

Семантика - множество правил интерпретации смысла предложения.

Синтаксический анализ - построение дерева грамматического разбора обрабатываемого текста. Текст состоит из предложений.

Результат анализа исходного предложения в терминах грамматических конструкций представляется в виде дерева. Такие деревья обычно называются деревьями грамматического разбора или синтаксическими деревьями.

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

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

Таблица литералов - таблица, содержащая литералы (константы), их тип и другую информацию. Литералу выделяется ячейка памяти, в которую записывается константа. Далее все появления этого литерала заменяются обращениями по адресу этой ячейки.

Результат работы сканера - последовательность кодов лексем. Код лексемы представляется кодом таблицы и спецификатором. Спецификатор задает номер строки в таблице, куда занесена лексема.

Оптимизирующие преобразования

Использование возможностей автоматической оптимизации компилятора может дать значительный выигрыш в производительности

Удаление общих подвыражений

Если одно и то же подвыражение встречается несколько раз, компилятор может вычислить его один раз, а все последующие включения заменяются вычисленным значением:

 a = (b+35) * (b+35);
c = 12.0 * (b+35);

в результате удаления общего подвыражения превращается в следующий:

tmp = b + 35;
a = tmp * tmp;
c = 12.0 * tmp;
Развертка цикла

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

ifor (i = 0; i < 2; i++) a[i] = 2.0 * d[i];

После развертки:

a[0] = 2.0 * d[0];
a[1] = 2.0 * d[1];
a[2] = 2.0 * d[2];