Многопроходный компилятор

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску

Многопроходный компилятор (англ. Multi-pass compiler) — тип компилятора, который обрабатывает исходный код или абстрактное синтаксическое дерево программы несколько раз (в отличие от однопроходного компилятора, который проходит программу только один раз). Между проходами генерируется промежуточный код, который принимается следующим проходом в качестве входа. Таким образом, многопроходный компилятор обрабатывает код по частям, проход за проходом, а последний проход выдает финальный результат программы.

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

Типичный многопроходный компилятор[править | править код]

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

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

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

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

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

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

if (условие) {
  ... 
} else {
  ...
}

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

Генерация кода[править | править код]

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

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

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

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

 var x:Integer;
 procedure inc;
 begin
	 x:=x+1;
 end;
 x:=0;
 inc;

В однопроходном компиляторе сначала создается ссылка на переменную x, и при её использовании компилятор уже знает о её декларации, поэтому всё будет семантически правильно.

  • Указания, где переменная х находится
  • Тип данных x

Такие языки программирования, как Java, используют многопроходные компилятор, позволяя создавать декларации переменных в коде позже использования. Пример показывает, что сначала мы используем переменную х, а потом следует её декларация.

 public class Example {	
	 public static void main(String [] args) {
		 assert(x==0);			
		 x++;
		 assert(x==1);
	 }
	 static int x=0;
 }