Введение
Инструмент разработки программного обеспечения. Многопроходный компилятор — это тип компилятора, который многократно обрабатывает исходный код или абстрактное синтаксическое дерево программы. Это отличается от однопроходного компилятора, который обходит программу только один раз. Каждый проход принимает результат предыдущего прохода в качестве входных данных и создает промежуточный результат. Таким образом, (промежуточный) код улучшается с каждым проходом, пока финальный проход не выдаст окончательный код. Многопроходные компиляторы иногда называют широкими компиляторами, подразумевая более широкий охват каждого прохода: они могут "видеть" всю компилируемую программу, а не только её часть. Этот расширенный охват позволяет таким компиляторам генерировать более качественный код (например, меньший размер или более высокую скорость выполнения) по сравнению с однопроходными компиляторами, но требует больше времени компиляции и потребления памяти. Кроме того, некоторые языки программирования по своей структуре не могут быть скомпилированы за один проход.
A multi pass compiler is a type of compiler that processes the source code or abstract syntax tree of a program several times. This is in contrast to a one pass compiler, which traverses the program only once. Each pass takes the result of the previous pass as the input, and creates an intermediate output. In this way, the (intermediate) code is improved pass by pass, until the final pass produces the final code. Multi pass compilers are sometimes called wide compilers, referring to the greater scope of the passes: they can "see" the entire program being compiled, instead of just a small portion of it. The wider scope thus available to these compilers allows better code generation (e. g. smaller code size, faster code) compared to the output of one pass compilers, at the cost of higher compiler time and memory consumption. In addition, some languages cannot be compiled in a single pass, as a result of their design.
Лексический анализ
Этот этап многопроходного компилятора предназначен для удаления из исходной программы нерелевантной информации, которую синтаксический анализ не сможет использовать или интерпретировать. Нерелевантная информация может включать в себя комментарии и пробелы. Помимо удаления нерелевантной информации, лексический анализ определяет лексические токены языка. Этот шаг означает, что предварительное объявление, как правило, не требуется при использовании многопроходного компилятора. На этом этапе основное внимание уделяется разбивке последовательности символов на токены с атрибутами, такими как тип, вид, значение и, возможно, другие.
Синтаксисный анализ
Синтаксический анализ отвечает за проверку синтаксических правил языка (часто представленных в виде контекстно-свободной грамматики) и создание некоторого промежуточного представления языка. Примером такого представления может служить абстрактное синтаксическое дерево или направленный ациклический граф.
Создание кода
Этот последний этап типичного компилятора преобразует промежуточное представление программы в исполняемый набор инструкций (часто ассемблерный код). Этот заключительный этап – единственный этап компиляции, зависящий от аппаратной платформы. На этом этапе компиляции также может выполняться оптимизация, повышающая эффективность программы. Другие этапы компилятора включают фазу генерации промежуточного кода, которая происходит перед генерацией кода, и фазу оптимизации кода, которая может выполняться при написании исходной программы, после генерации промежуточного кода или после генерации кода.
Преимущества многопроходных компиляторов
Независимость от аппаратной платформы: Благодаря модульной структуре многопроходной компиляции и отделению генерации кода от других этапов компилятора, проходы могут быть повторно использованы для различных аппаратных средств и машин. Более выразительные языки программирования: Многопроходная компиляция устраняет необходимость во "прямых объявлениях", позволяя элегантно реализовывать взаимную рекурсию. Яркими примерами языков, требующих прямых объявлений из-за необходимости однопроходной компиляции, являются C и Pascal, в то время как в Java прямые объявления отсутствуют.