Для реализации задач, описанных в программном коде, процессор компьютера должен произвести ряд операций. Но процессор, как и другие части компьютерного «железа», не понимает языки программирования высокого уровня. Поэтому для того, чтобы добиться исполнения описанных в программе действий, её переводят в понятный процессору объектный код. Конечный результат этого перевода называется объектным модулем или объектным файлом и содержит в себе набор единичек и нулей, понятных процессору компьютера.
Для проведения переводов исходного кода в объектный или промежуточный код используются специальные программы – трансляторы.
Что такое транслятор?
Транслятор (от английского Translate – переводить) - программа, переводящая исходный код (программу, написанную на одном из высокоуровневых языков программирования) в объектный код, используемый процессором компьютера, или в промежуточный код для последующей интерпретации.
Помимо осуществления перевода, трансляторы могут выявлять в исходном коде ошибки, оптимизировать исходный код, добавлять в исходный код отладочные процедуры, формировать словари идентификаторов и другое.
Существуют также обратные трансляторы, осуществляющие перевод с машинного кода в понятный пользователю язык программирования.
В тех случаях, когда исходный код переводится для последующего исполнения процессором, для трансляции используется компилятор.
Что такое компилятор?
Компилятор (от английского Compile – собирать, накапливать) – это вариант реализации транслятора, который создаётся для перевода программы, написанной на высокоуровневом языке программирования в машинный код, который в последствие будет исполняться процессором компьютера. Этот тип трансляции называется компиляцией.
В большинстве случаев компиляция программы происходит полностью (AOT-компиляция). Компилятор целиком считывает программу, проводит её пошаговый анализ (лексический, синтаксический, семантический), оптимизирует её, очищая от излишних конструкций, но сохраняя исходный смысл операций, и также целиком переводит её в машинный код.
Однако, иногда используется и построчная компиляция. В этом случае машинный код генерируется и исполняется для каждой полной грамматической конструкции исходного кода. От интерпретации такая компиляция отличается способом исполнения.
Для каждого языка программирования и практически для каждой операционной системы используется свой компилятор. Иногда для одного семейства операционных систем может использоваться один и тот же компилятор.
Компиляторы для C++
Так, например, для C++ можно использовать:
- Microsoft Visual C++ 6.0
- MS Visual Studio 2005 Professional
- Intel C++ Compiler 4.5
- Borland Builder 6.0
- Borland C++ Compiler
- g++
- gcc
- MinGW 3.2
Подходящий компилятор выбирается, исходя из особенностей программ, с которыми предстоит работать и, как уже говорилось выше, операционной системы.
Компилятор для Python
Необходимость самостоятельно компилировать исходный код с Питона в exe-файл для последующей интерпретации возникает нечасто. В тех случаях, когда на компьютер, на котором планируется выполнение программы, уже установлен интерпретатор Python, компиляция обычно не требуется.
Если программе всё же необходима компиляция, можно использовать cx_Freeze.
Компилятор для Java
Язык программирования Java работает с виртуальной машиной Java, которая обрабатывает байт-код (промежуточный код) и передаёт инструкции оборудованию. Виртуальная машина Java, по сути, является интерпретатором.
Компиляторы в Java используются для того, чтобы преобразовать исходный код в байт-код, доступный пониманию виртуальной машины и пригодный для последующей интерпретации.
Чаще всего используются:
- GNU Compiler for Java
- Javac
Javac помимо анализа и трансляции, производит ещё и оптимизацию кода.
В целом, за счёт использования виртуальной машины, Java выполняет операции, описанные в исходном коде куда медленнее, чем, скажем, С++. При исполнении некоторых операций Java может уступать в скорости до 7 раз. Для ускорения работы программ на Java используется оптимизация библиотек (в них широко используется native-код), некоторые аппаратные решения для ускоренной обработки байт-кода и JIT-компиляция.
JIT-компиляция
JIT-компиляция – это трансляция байт-кода в машинный код непосредственно во время работы программы. JIT-компиляция может быть применена к любой части программы или ко всей программе в целом.
Использование этой технологии позволяет существенно ускорить процесс исполнения задач, поставленных в исходном коде, по сравнению с пошаговой интерпретацией, традиционно применяемой виртуальными машинами.
Что такое интерпретатор?
Интерпретатор (от английского Interpret – толковать) – программа, выполняющая пошаговую обработку исходного кода, его анализ и техническую реализацию этой же части кода.
Проще говоря, в отличие от большинства компиляторов, интерпретатор обрабатывает, а затем исполняет не всю исходную программу, а отдельно каждую её строку, пока программа не будет закончена.
Интерпретаторы бывают двух типов:
- Простые - осуществляющие исключительно интерпретацию введённого исходного кода.
- Интерпретаторы компилирующего типа – это система, состоящая из компилятора, транслирующего исходный код в промежуточный, и виртуальной машины, реализующей операции, описанные в коде.
Виртуальная машина
Во многих языках программирования реализацию написанного исходного кода выполняет виртуальная машина. Это часть интерпретатора, получающая на вводе скомпилированный промежуточный код и выполняющая описанные в нём операции.
Давайте рассмотрим алгоритм этого процесса на примере PVM (Python Virtual Machine).
По схожей схеме работают виртуальная машина Java, Common Language Runtime (инструмент для интерпретации С#) и некоторые другие интерпретаторы.
Интерпретатор для PHP
Интерпретатор PHP отличается от большей части виртуальных машин отсутствием создания выполняемого файла. То есть в отличие от, скажем, PVM (Python Virtual Machine) он не кеширует сгенерированный байт-код в памяти. Потому при запуске и отладке программы компиляция одного и того же фрагмента байт-кода происходит несколько раз. Это существенно замедляет работу программы.
Сравнение интерпретаторов и компиляторов
Плюсы интерпретаторов
- Использование для реализации исходного кода виртуальной машины позволяет интерпретаторам эффективно работать на всех платформах.
- С интерпретатором можно работать в интерактивном режиме.
Минусы интерпретаторов
- Исходный код не может работать отдельно без наличия интерпретатора.
Плюсы компиляторов
- Возможность эффективной оптимизации кода, сокращающей количество операций и итоговое время выполнения поставленных программе задач.
- Быстродействие – перевод в машинный код и реализация операций процессором происходит в среднем в 1,5 раза быстрее, чем пошаговая трансляция программы в байт-код и последующая реализация её виртуальной машиной.
- Производительность – исполнимый модуль, получившийся в результате компиляции, обладает оптимальными показателями скорости выполнения и задействует в работе минимум ресурсов компьютера.
Минусы компиляторов
- И сами компиляторы, и генерируемый ими код рассчитаны на использование в определённой операционной системе и взаимодействие с определённым типом процессора. В других исходных условиях они работать не будут.
Выбор транслятора
Выбор транслятора для работы с той или иной программой, прежде всего, определяется рекомендациями разработчиков этой программы, затем, целями и личными предпочтениями программиста.
Если Вы хотите разобраться в этой теме глубже, рекомендуем прочесть:
Альфред В. Ахо, Моника С. Лам, Рави Сети, Джеффри Д. Ульман. Компиляторы: принципы, технологии и инструментарий
Это учебник по теории написания компиляторов, в котором подробно описаны принципы работы разноуровневых компиляторов (начиная от простейших однопроходных, заканчивая современным компилятором на языке Java), уделяется повышенное внимание лексическому, синтаксическому и семантическому разбору программ в исходном коде, генерации машинного кода.
В.А.Серебряков, М.П.Галочкин. Основы конструирования компиляторов
Ещё один учебник по созданию компиляторов, только теперь отечественный. Глубоко раскрыты темы лексического и семантического анализа, рассмотрены темы автоматизации процесса разработки компиляторов, получения оптимального кода.