Определение и цель компилятора

Компилятор — это программа, которая переводит читаемый человеком исходный код в исполняемый компьютером машинный код. Чтобы сделать это успешно, человеко-читаемый код должен соответствовать правилам синтаксиса того языка программирования, на котором он написан. Компилятор — это всего лишь программа и не может исправить ваш код за вас. Если вы допустили ошибку, вам нужно исправить синтаксис, иначе он не будет компилироваться.

Что происходит при компиляции кода?

Сложность компилятора зависит от синтаксиса языка и степени абстракции, которую предоставляет язык программирования. Компилятор AC намного проще, чем компилятор для C ++ или C #.

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

При компиляции компилятор сначала читает поток символов из файла исходного кода и генерирует поток лексических токенов. Например, код C ++:

 
 int C = (A * B) +10; 

могут быть проанализированы как эти токены:

  • type » int «
  • переменная» C «
  • равно
  • левая квадратная скобка
  • переменной» A «
  • раз
  • переменная «B»
  • правая скобка
  • плюс
  • литерал «10»

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

Лексический вывод поступает в часть синтаксического анализатора компилятора, который использует правила грамматики, чтобы решить, действителен ли ввод или нет. Если переменные A и B не были ранее объявлены и не попали в область видимости, компилятор может сказать:

  • ‘A’: необъявленный идентификатор.

Если они были объявлены, но не инициализированы. компилятор выдает предупреждение:

  • локальная переменная ‘A’ используется без инициализации.

Никогда не игнорируйте предупреждения компилятора. Они могут взломать ваш код странным и неожиданным образом. Всегда исправлять предупреждения компилятора.

Один проход или два?

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

В C ++ класс может быть объявлен, но не определен позже. Компилятор не может определить, сколько памяти требуется классу, пока он не скомпилирует тело класса. Он должен перечитать исходный код перед генерацией правильного машинного кода.

Генерация машинного кода

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

Скорость скомпилированного исполняемого кода должна быть максимально высокой и может сильно различаться в зависимости от качества. сгенерированного кода и сколько оптимизации было запрошено.

Большинство компиляторов позволяют вам указать степень оптимизации — обычно это известно благодаря быстрой отладочной компиляции и полной оптимизации выпущенного кода.

Создание кода затруднительно

Автор компилятора сталкивается с проблемами при написании генератора кода. Многие процессоры ускоряют обработку за счет использования

  • конвейерной обработки инструкций
  • внутренних кешей.

Если все инструкции в цикле кода могут храниться в кеше ЦП, то этот цикл выполняется намного быстрее, чем когда ЦП должен получать инструкции из основного ОЗУ. . Кэш ЦП — это блок памяти, встроенный в микросхему ЦП, доступ к которому происходит намного быстрее, чем к данным в основной ОЗУ.

Кеши и очереди

У большинства ЦП есть очередь предварительной выборки, в которой ЦП считывает инструкции в кэш перед их выполнением. Если происходит условный переход, ЦП должен перезагрузить очередь. Код должен быть сгенерирован, чтобы минимизировать это.

Многие процессоры имеют отдельные части для:

  • Целочисленная арифметика (целые числа)
  • Арифметика с плавающей запятой (дробные числа)

Эти операции часто могут выполняться параллельно для увеличения скорости.

Компиляторы обычно генерируют машинный код в объектные файлы, которые затем связываются вместе программой компоновщика.

Оцените статью
recture.ru
Добавить комментарий