Введение

Инструмент разработки программного обеспечения. Многопроходный компилятор — это тип компилятора, который многократно обрабатывает исходный код или абстрактное синтаксическое дерево программы. Это отличается от однопроходного компилятора, который обходит программу только один раз. Каждый проход принимает результат предыдущего прохода в качестве входных данных и создает промежуточный результат. Таким образом, (промежуточный) код улучшается с каждым проходом, пока финальный проход не выдаст окончательный код. Многопроходные компиляторы иногда называют широкими компиляторами, подразумевая более широкий охват каждого прохода: они могут "видеть" всю компилируемую программу, а не только её часть. Этот расширенный охват позволяет таким компиляторам генерировать более качественный код (например, меньший размер или более высокую скорость выполнения) по сравнению с однопроходными компиляторами, но требует больше времени компиляции и потребления памяти. Кроме того, некоторые языки программирования по своей структуре не могут быть скомпилированы за один проход.

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

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

Синтаксисный анализ

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

Создание кода

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

Преимущества многопроходных компиляторов

Независимость от аппаратной платформы: Благодаря модульной структуре многопроходной компиляции и отделению генерации кода от других этапов компилятора, проходы могут быть повторно использованы для различных аппаратных средств и машин. Более выразительные языки программирования: Многопроходная компиляция устраняет необходимость во "прямых объявлениях", позволяя элегантно реализовывать взаимную рекурсию. Яркими примерами языков, требующих прямых объявлений из-за необходимости однопроходной компиляции, являются C и Pascal, в то время как в Java прямые объявления отсутствуют.