Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Компиляторы.docx
Скачиваний:
19
Добавлен:
09.11.2018
Размер:
328.9 Кб
Скачать

Глава 2

Простой однопроходный компилятор

Данная глава является вводной к главам 3-8 и представляет ряд базовых технологий компиляции, проиллюстрированных разработкой рабочей программы на С, которая транслирует инфиксные выражения в постфиксную форму. Здесь основное внимание уделяется предварительной стадии компиляции, т.е. лексическому анализу, разбору и ге­нерации промежуточного кода. Главы 9, "Генерация кода", и 10, "Оптимизация кода" посвящены вопросам генерации и оптимизации кода.

2.1. Обзор

Язык программирования может быть определен с помощью описания того, как должна выглядеть программа (синтаксис языка) и что она означает (семантика языка). Для опре­деления синтаксиса языка рекомендуем широко применяемую запись, называемую контек­стно-свободной грамматикой, или BNF (Backus-Naur Form, форма Бэкуса-Наура). На сего­дня описание семантики языка — гораздо более сложная задача, чем описание синтаксиса; для ее решения необходимо использовать неформальные описания и примеры.

Кроме определения синтаксиса языка, контекстно-свободная грамматика использует­ся при трансляции программ. Грамматически управляемая технология компиляции, из­вестная также как синтаксически управляемая трансляция (syntax-directed translation), очень полезна при разработке предварительной стадии компилятора и будет широко ис­пользоваться в данной главе.

В процессе обсуждения синтаксически управляемой трансляции мы построим компи­лятор, переводящий инфиксные выражения в постфиксные, в которых операторы появ­ляются после своих операндов. Например, постфиксная форма выражения 9 - 5 + 2 выгля­дит как 9 5-2+. Постфиксная запись может быть преобразована непосредственно в компьютерный код, который выполняет все необходимые вычисления с использованием стека. Давайте начнем с построения простой программы для трансляции в постфиксную форму выражений из цифр, разделенных знаками "плюс" и "минус". После того как ста­нет понятна основная идея, мы расширим программу для обработки более общих конст­рукций языка программирования. Каждый из наших трансляторов будет представлять собой расширение предыдущего.

В нашем компиляторе лексический анализатор конвертирует поток входных симво­лов в поток токенов, которые представляют собой входной поток для следующей фазы, как показано на рис. 2.1. В данном случае "синтаксически управляемый транслятор" представляет собой комбинацию синтаксического анализатора и генератора промежу­точного кода. Одна из причин, по которой мы первоначально ограничиваемся только выражениями, состоящими из цифр и операторов, — простота лексического анализатора (каждый входной символ представляет собой отдельный токен). Позже мы расширим наш язык, включив в него такие лексические конструкции, как числа, идентификаторы и ключевые слова. Для такого расширенного языка мы построим лексический анализатор, который будет накапливать последовательные символы из входного потока и преобразо­вывать их в токены. Детально построение такого лексического анализатора будет рас­смотрено в главе 3, "Лексический анализ".

Рис. 2.1. Структура предварительной стадии компилятора