Введение

Преобразование компьютерного кода в машиночитаемую форму

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

Создание кода во время выполнения

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

Связанные понятия

Основная задача получения входных данных на одном языке и выдачи выходных данных на существенно отличающемся языке может быть понята в терминах основных преобразующих операций теории формальных языков. Следовательно, некоторые методы, изначально разработанные для компиляторов, стали применяться и в других областях. Например, YACC (Yet Another Compiler Compiler) принимает входные данные в форме Бэкуса — Наура и преобразует их в парсер на языке C. Хотя изначально он был создан для автоматической генерации парсера для компилятора, yacc также часто используется для автоматизации написания кода, который необходимо изменять при каждом изменении спецификаций. Многие интегрированные среды разработки (IDE) поддерживают ту или иную форму автоматической генерации исходного кода, часто используя алгоритмы, общие с генераторами кода компиляторов, хотя обычно менее сложные. (См. также: Преобразование программ, Преобразование данных.)

Отражение

В целом, синтаксический и семантический анализатор стремится получить структуру программы из исходного кода, а генератор кода использует эту структурную информацию (например, типы данных) для генерации кода. Иными словами, первый добавляет информацию, а второй часть информации теряет. Одним из последствий этой потери информации является то, что рефлексия становится затруднительной или даже невозможной. Чтобы решить эту проблему, генераторы кода часто внедряют синтаксическую и семантическую информацию, помимо кода, необходимого для исполнения.