Компилятор

КОМПИЛЯТОР (от латинского compilo - собирать, составлять, компилировать) в информатике, компьютерная программа, которая преобразует исходный код программы на языке программирования высокого уровня (ЯПВУ) в функционально эквивалентный набор инструкций на языке низкого уровня (так называемый объектный код). Компилятор  является одним из видов транслятора и, как правило, входит в состав системного программного обеспечения компьютера. Каждый компилятор соответствует определённому ЯПВУ (паскалю, си, фортрану и др.) и одной или нескольким вычислительным платформам. Вычислительная платформа определяется архитектурой семейства центральных процессоров; например, х86 - Intel 8086 Family Architecture (архитектура семейства Intel 8086), операционной системой и, в ряде случаев, дополнительным программным обеспечением (например, виртуальной машиной), необходимым для работы исполняемого кода на процессорах данной архитектуры.

Компилятор  выполняет лексический, синтаксический, семантический анализ исходного кода программы и генерацию объектного кода. На этапе лексического анализа исходный код преобразуется в последовательность лексических единиц - лексем (ключевые слова языка программирования, идентификаторы переменных, константы и др.). Во время синтаксического анализа осуществляется проверка последовательности лексем на наличие синтаксических ошибок (в соответствии с синтаксическими правилами языка программирования) и затем - преобразование этой последовательности в так называемое дерево разбора. Семантический анализ предназначен для выявления логических ошибок в исходной программе и определения значения языковых конструкций дерева разбора. После этого компилятор либо переходит к генерации объектного кода, либо завершает работу выводом сообщения об ошибках. Исходный код программы, как правило, содержится в нескольких файлах. Компилятор  преобразует каждый из них в отдельный объектный модуль (файл, содержащий объектный код), а затем специальная программа-компоновщик собирает исполняемый код программы из объектных модулей, стандартных библиотечных модулей и др. До создания компоновщиков сборка производилась компилятором.

Реклама

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

Альтернативой компиляторам и компоновщикам служат интерпретаторы. Для ряда ЯПВУ существуют как компиляторы, так и интерпретаторы. Для некоторых ЯПВУ (например, Java) применяется двухэтапная компиляция или сочетание компиляции и интерпретации. На первом этапе на специальном промежуточном языке генерируется так называемый байт-код, который не привязан к конкретной операционной системе и архитектуре семейства процессоров. Байт-код предназначен для последующей интерпретации или так называемый JIT-компиляции (Just-In-Time compilation - компиляция «на лету») во время выполнения программы. На втором этапе преобразование байткода в исполняемый код (для конкретной операционной системы и процессора) осуществляется специальным программным обеспечением (например, Java Virtual Machine - виртуальной машиной Java). Такой подход позволяет существенно уменьшить трудозатраты программистов, поскольку один и тот же байт-код может быть использован на различных вычислительных платформах, включающих необходимую виртуальную машину. С конца 20 века большое внимание уделяется созданию так называемых двоичных компиляторов, которые позволяют переводить скомпонованный исполняемый код одной платформы в код альтернативной архитектурной платформы, обеспечивая перенос готового программного обеспечения.

Компиляторы  классифицируют по различным признакам: по времени запуска процесса компиляции, по классу целевых архитектур, по наличию оптимизирующих преобразований и др. По времени запуска различают компиляторы статические и динамические. Статический компилятор запускается программистом из инструментальной системы программирования или командной строки. Динамический компилятор запускается во время работы программы, т. е. параллельно с исполнением программы идёт перекомпиляция некоторых её частей. На основе классов целевых архитектур процессоров различают компиляторы для архитектур с явно выраженным параллелизмом (EPIC - Explicitly Parallel Instruction Computing), для встроенных (embedded) архитектур, автоматические распараллеливатели для многоядерных (multicore) архитектур и др.

Один из первых компиляторов разработан в 1952 Г. Хоппер (США) для созданного ею языка программирования А-0 ЭВМ UNIVAC I. До появления ЯПВУ и их компиляторов программы писали на языках низкого уровня (сначала в кодах машинных команд, позднее - на языках ассемблера). Значительным достижением автоматизации программирования стала разработка в 1957 году компилятора для языка фортран ЭВМ IBM 704, выполненная под руководством Дж. Бэкуса (США). В 1950-60-х годах исходные коды компилятора писались только на языках ассемблера. Одной из первых российских работ в области оптимизирующей компиляции стал Альфа-транслятор с языка алгол-60 для ЭВМ М-20, созданный под руководством А. П. Ершова (1959-64). В 1970-х годах реализованы ЯПВУ паскаль, си и др., которые стали применяться как для создания прикладных программ, так и для разработки компиляторов, что привело к значительному сокращению трудоёмкости создания компиляторов. Рост числа ЯПВУ и различных вычислительных платформ обусловливает появление новых компиляторов и совершенствование методов их конструирования.

Лит.: Compilers: principles, techniques and tools. 2nd ed. Boston, 2007.

А. Ю. Дроздов, А. В. Ильин.