Компилятор
Компиля́тор (от англ. compile – выбирать, собирать, составлять, от лат. compilo – разграблять, расхищать) в информатике, компьютерная программа, которая преобразует исходный код программы на языке программирования высокого уровня (ЯПВУ) в функционально эквивалентный набор инструкций на языке низкого уровня (т. н. объектный код). Как правило, входит в состав системного программного обеспечения компьютера. Каждый компилятор соответствует определённому ЯПВУ (Pascal, C, Fortran и др.) и одной или нескольким вычислительным платформам. Вычислительная платформа определяется архитектурой семейства центральных процессоров, например, x86 – Intel 8086 Family Architecture (архитектура семейства Intel 8086); операционной системой и, в ряде случаев, дополнительным программным обеспечением (например, виртуальной машиной), необходимым для работы исполняемого кода на процессорах данной архитектуры.
Компилятор выполняет лексический, синтаксический, семантический анализ исходного кода программы и генерацию объектного кода. На этапе лексического анализа исходный код преобразуется в последовательность лексических единиц – лексем (ключевые слова языка программирования, идентификаторы переменных, константы и др.). Во время синтаксического анализа осуществляется проверка последовательности лексем на наличие синтаксических ошибок (в соответствии с синтаксическими правилами языка программирования) и затем – преобразование этой последовательности в т. н. дерево разбора. Семантический анализ предназначен для выявления логических ошибок в исходной программе и определения значения языковых конструкций дерева разбора. После этого компилятор либо переходит к генерации объектного кода, либо завершает работу выводом сообщения об ошибках. Исходный код программы, как правило, содержится в нескольких файлах. Компилятор преобразует каждый из них в отдельный объектный модуль (файл, содержащий объектный код), а затем специальная программа – компоновщик собирает исполняемый код программы из объектных модулей, стандартных библиотечных модулей и др. До создания компоновщиков сборка производилась компилятором.
Для эффективного использования особенностей архитектуры процессоров и улучшения характеристик исполняемого кода (производительности, компактности и др.) в компилятор встроены компоненты, оптимизирующие код.
Альтернативой компилятору и компоновщикам служат интерпретаторы. Для ряда ЯПВУ существуют как компиляторы, так и интерпретаторы. Для некоторых ЯПВУ (например, Java) применяется двухэтапная компиляция или сочетание компиляции и интерпретации. На первом этапе на специальном промежуточном языке генерируется т. н. байт-код, который не привязан к конкретной операционной системе и архитектуре семейства процессоров. Байт-код предназначен для последующей интерпретации или т. н. JIT-компиляции (от англ. Just-In-Time Compilation – компиляция «на лету») во время выполнения программы. На втором этапе преобразование байт-кода в исполняемый код (для конкретных операционной системы и процессора) осуществляется специальным программным обеспечением (например, Java Virtual Machine – виртуальной машиной Java). Такой подход позволяет существенно уменьшить трудозатраты программистов, поскольку один и тот же байт-код может быть использован на различных вычислительных платформах, включающих необходимую виртуальную машину. С конца 20 в. большое внимание уделяется созданию т. н. двоичных компиляторов, которые позволяют переводить скомпонованный исполняемый код одной платформы в код альтернативной архитектурной платформы, обеспечивая перенос готового программного обеспечения.
Компиляторы классифицируют по различным признакам: по времени запуска процесса компиляции, по классу целевых архитектур, по наличию оптимизирующих преобразований и др. По времени запуска различают компиляторы статические и динамические. Статический компилятор запускается программистом из инструментальной системы программирования или командной строки. Динамический компилятор запускается во время работы программы, т. е. параллельно с исполнением программы идёт перекомпиляция некоторых её частей. На основе классов целевых архитектур процессоров различают компилятор для архитектур с явно выраженным параллелизмом (англ. Explicitly Parallel Instruction Computing – EPIC), для встроенных (англ. embedded) архитектур, автоматические распараллеливатели для многоядерных (англ. multicore) архитектур и др.
Один из первых компиляторов разработан в 1952 г. Г. Хоппер (США) для ЭВМ UNIVAC I. До появления ЯПВУ и их компиляторов программы писали на языках низкого уровня (сначала в кодах машинных команд, позднее – на языках ассемблера). Значительным достижением автоматизации программирования стала разработка в 1957 г. компилятора для языка Fortran ЭВМ IBM 704, выполненная под руководством Дж. Бэкуса (США). В 1950–1960-х гг. исходные коды компилятора писались только на языках ассемблера. Одной из первых российских работ в области оптимизирующей компиляции стал Альфа-транслятор с языка Algol-60 для ЭВМ М-20, созданный под руководством А. П. Ершова (1959–1964). В 1970-х гг. реализованы ЯПВУ Pascal, C и др., которые стали применяться как для создания прикладных программ, так и для разработки компиляторов, что привело к значительному сокращению трудоёмкости создания компиляторов. Рост числа ЯПВУ и различных вычислительных платформ обусловливает появление новых компиляторов и совершенствование методов их конструирования.