компилятор это программа что переводит читабельный человек исходный код в машинно-исполняемый машинный код. Чтобы сделать это успешно, читабельный код должен соответствовать синтаксис правила того, на каком языке программирования он написан. Компилятор является только программой и не может исправить ваш код для вас. Если вы допустили ошибку, вы должны исправить синтаксис, иначе он не скомпилируется.
Что происходит, когда вы компилируете код?
Сложность компилятора зависит от синтаксиса языка и степени абстракции этот язык программирования обеспечивает. Компилятор C намного проще, чем компилятор для C ++ или C #.
Лексический анализ
При компиляции компилятор сначала читает поток символов из файла исходного кода и генерирует поток лексических токенов. Например, код C ++:
int C = (A * B) +10;
могут быть проанализированы как эти токены:
- введите "int"
- переменная "C"
- равно
- leftbracket
- переменная "А"
- раз
- переменная "B"
- rightbracket
- плюс
- буквальное "10"
Синтаксический анализ
Лексический вывод поступает в часть синтаксического анализатора компилятора, который использует правила грамматики, чтобы решить, является ли ввод действительным или нет. Если не
переменные A и B были ранее объявлены и находились в области видимости, компилятор мог бы сказать:- «А»: необъявленный идентификатор.
Если они были объявлены, но не инициализированы. компилятор выдает предупреждение:
- локальная переменная «А» используется без инициализации.
Вы никогда не должны игнорировать предупреждения компилятора. Они могут сломать ваш код странным и неожиданным образом. Всегда исправляйте предупреждения компилятора.
Один проход или два?
Некоторые языки программирования написаны так, что компилятор может прочитать исходный код только один раз и сгенерировать машинный код. паскаль один из таких языков. Много составители требуется как минимум два прохода. Иногда это происходит из-за предварительных заявлений функции или классы.
В C ++ класс может быть объявлен, но не определен до более позднего времени. Компилятор не может определить, сколько памяти нужно классу, пока не скомпилирует тело класса. Он должен перечитать исходный код перед генерацией правильного машинного кода.
Генерация машинного кода
Предполагая, что компилятор успешно завершает лексический и синтаксический анализ, заключительным этапом является генерация машинного кода. Это сложный процесс, особенно с современными процессорами.
Скорость скомпилирована исполнимый код должен быть максимально быстрым и может сильно отличаться в зависимости от качества сгенерированного кода и степени оптимизации.
Большинство компиляторов позволяют вам указать объем оптимизации - обычно известный как быстрая отладка компиляций и полная оптимизация для выпущенного кода.
Генерация кода является сложной задачей
Автор компилятора сталкивается с проблемами при написании генератора кода. Многие процессоры ускоряют обработку, используя
- Инструкция по прокладке трубопровода
- внутренний кэши.
Если все инструкции в коде петля можно провести в Процессор кеш, тогда этот цикл выполняется намного быстрее, чем когда ЦП должен извлекать инструкции из основного ОЗУ. Кэш ЦП - это блок памяти, встроенный в чип ЦП, доступ к которому осуществляется гораздо быстрее, чем данные в основной ОЗУ.
Тайники и очереди
У большинства процессоров есть очередь предварительной выборки, где процессор считывает инструкции в кэш перед их выполнением. Если происходит условная ветвь, ЦП должен перезагрузить очередь. Код должен быть сгенерирован, чтобы минимизировать это.
Многие процессоры имеют отдельные части для:
- Целочисленная арифметика (целые числа)
- Арифметика с плавающей точкой (дробные числа)
Эти операции часто могут выполняться параллельно для увеличения скорости.
Компиляторы обычно генерируют машинный код в объектные файлы, которые затем связанный вместе с помощью программы компоновщика.