Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебное пособие 700383.doc
Скачиваний:
15
Добавлен:
01.05.2022
Размер:
4.33 Mб
Скачать

9.1.4. Этапы трансляции. Общая схема работы транслятора

На рис. 27 представлена общая схема работы компилятора, из которой видно, что в целом процесс компиляции состоит из двух основных этапов - анализа и синтеза.

На этапе анализа выполняется следующее:

  • распознавание текста исходной программы;

  • создание и заполнение таблиц идентификаторов.

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

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

Рис. 27. Общая схема работы компилятора

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

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

Компилятор в целом с точки зрения теории формальных языков выполняет следующие основные функции:

1. Компилятор является распознавателем для языка исходной программы. То есть он должен получить на вход цепочку символов входного языка, проверить ее принадлежность языку и, более того, выявить правила, по которым эта цепочка была построена (поскольку на вопрос о принадлежности сам ответ «да» или «нет» представляет мало интереса). Интересно, что генератором цепочек входного языка выступает пользователь - автор исходной программы.

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

Рассмотрим перечень основных фаз (частей) компиляции и краткое описание их функций.

Лексический анализ (сканер) – это часть компилятора, которая читает литеры программы на исходном языке и строит из них слова (лексемы) исходного языка. Работа его заключается в следующем:

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

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

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

Синтаксический разборэто основная часть компилятора на этапе анализа. Она предназначена для следующего:

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

  • проверяется синтаксическая правильность программы.

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

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

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

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

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

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

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

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

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

Представленное на рис. 26 деление процесса компиляции на фазы служит скорее методическим целям и на практике может не соблюдаться столь строго.

Далее рассмотрим общие аспекты взаимосвязи фаз компиляции:

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

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

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