Содержание

Компилятор | это… Что такое Компилятор?

Эта статья включает описание термина «Компиляция»; см. также другие значения.

Компиля́тор — программа или техническое средство, выполняющее компиляцию.[1][2][3]

Компиляция — трансляция программы, составленной на исходном языке высокого уровня, в эквивалентную программу на низкоуровневом языке, близком машинному коду (абсолютный код, объектный модуль, иногда на язык ассемблера).[2][3][4] Входной информацией для компилятора (исходный код) является описание алгоритма или программа на проблемно-ориентированном языке, а на выходе компилятора — эквивалентное описание алгоритма на машинно-ориентированном языке (объектный код).[5]

Компилировать — проводить трансляцию машинной программы с проблемно-ориентированного языка на машинно-ориентированный язык.[3]

Содержание

  • 1 Виды компиляторов[2]
  • 2 Виды компиляции
    [2]
  • 3 Структура компилятора
  • 4 Генерация кода
    • 4. 1 Генерация машинного кода
    • 4.2 Генерация байт-кода
    • 4.3 Динамическая компиляция
    • 4.4 Декомпиляция
  • 5 Раздельная компиляция
  • 6 Интересные факты
  • 7 См. также
  • 8 Примечания
  • 9 Литература

Виды компиляторов

[2]
  • Векторизующий. Транслирует исходный код в машинный код компьютеров, оснащённых векторным процессором.
  • Гибкий. Сконструирован по модульному принципу, управляется таблицами и запрограммирован на языке высокого уровня или реализован с помощью компилятора компиляторов.
  • Диалоговый
    . См.: диалоговый транслятор.
  • Инкрементальный. Повторно транслирует фрагменты программы и дополнения к ней без перекомпиляции всей программы.
  • Интерпретирующий (пошаговый). Последовательно выполняет независимую компиляцию каждого отдельного оператора (команды) исходной программы.
  • Компилятор компиляторов. Транслятор, воспринимающий формальное описание языка программирования и генерирующий компилятор для этого языка.
  • Отладочный. Устраняет отдельные виды синтаксических ошибок.
  • Резидентный. Постоянно находится в оперативной памяти и доступен для повторного использования многими задачами.
  • Самокомпилируемый. Написан на том же языке, с которого осуществляется трансляция.
  • Универсальный. Основан на формальном описании синтаксиса и семантики входного языка. Составными частями такого компилятора являются: ядро, синтаксический и семантический загрузчики.

Виды компиляции

[2]
  • Пакетная. Компиляция нескольких исходных модулей в одном пункте задания.
  • Построчная. То же, что и интерпретация.
  • Условная. Компиляция, при которой транслируемый текст зависит от условий, заданных в исходной программе директивами компилятора. Так, в зависимости от значения некоторой константы, можно включать или выключать трансляцию части текста программы.

Структура компилятора

Процесс компиляции состоит из следующих этапов:

  1. Лексический анализ. На этом этапе последовательность символов исходного файла преобразуется в последовательность лексем.
  2. Синтаксический (грамматический) анализ. Последовательность лексем преобразуется в дерево разбора.
  3. Семантический анализ. Дерево разбора обрабатывается с целью установления его семантики (смысла) — например, привязка идентификаторов к их декларациям, типам, проверка совместимости, определение типов выражений и т. д. Результат обычно называется «промежуточным представлением/кодом», и может быть дополненным деревом разбора, новым деревом, абстрактным набором команд или чем-то ещё, удобным для дальнейшей обработки.
  4. Оптимизация. Выполняется удаление излишних конструкций и упрощение кода с сохранением его смысла. Оптимизация может быть на разных уровнях и этапах — например, над промежуточным кодом или над конечным машинным кодом.
  5. Генерация кода. Из промежуточного представления порождается код на целевом языке.

В конкретных реализациях компиляторов эти этапы могут быть разделены или, наоборот, совмещены в том или ином виде.

Генерация кода

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

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

Результат компиляции — исполнимый модуль — обладает максимальной возможной производительностью, однако привязан к определённой операционной системе и процессору (и не будет работать на других).

Для каждой целевой машины (IBM, Apple, Sun и т. д.) и каждой операционной системы или семейства операционных систем, работающих на целевой машине, требуется написание своего компилятора. Существуют также так называемые кросс-компиляторы, позволяющие на одной машине и в среде одной ОС генерировать код, предназначенный для выполнения на другой целевой машине и/или в среде другой ОС. Кроме того, компиляторы могут оптимизировать код под разные модели из одного семейства процессоров (путём поддержки специфичных для этих моделей особенностей или расширений наборов инструкций). Например, код, скомпилированный под процессоры семейства Pentium, может учитывать особенности распараллеливания инструкций и использовать их специфичные расширения — MMX, SSE и т. п.

Некоторые компиляторы переводят программу с языка высокого уровня не прямо в машинный код, а на язык ассемблера. Это делается для упрощения части компилятора, отвечающей за кодогенерацию, и повышения его переносимости (задача окончательной генерации кода и привязки его к требуемой целевой платформе перекладывается на ассемблер), либо для возможности контроля и исправления результата компиляции программистом.

Генерация байт-кода

Результатом работы компилятора может быть программа на специально созданном низкоуровневом языке, подлежащем интерпретации виртуальной машиной. Такой язык называется псевдокодом или байт-кодом. Как правило, он не является машинным кодом какого-либо компьютера и программы на нём могут исполняться на различных архитектурах, где имеется соответствующая виртуальная машина, но в некоторых случаях создаются аппаратные платформы, напрямую поддерживающие псевдокод какого-либо языка. Например, псевдокод языка Java называется байт-кодом Java и выполняется в Java Virtual Machine, для его прямого исполнения была создана спецификация процессора picoJava. Для платформы .NET Framework псевдокод называется Common Intermediate Language (CIL), а среда исполнения — Common Language Runtime (CLR).

Некоторые реализации интерпретируемых языков высокого уровня (например, Perl) используют байт-код для оптимизации исполнения: затратные этапы синтаксического анализа и преобразование текста программы в байт-код выполняются один раз при загрузке, затем соответствующий код может многократно использоваться без промежуточных этапов.

Динамическая компиляция

Основная статья: JIT-компиляция

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

CIL-код также компилируется в код целевой машины JIT-компилятором, а библиотеки .NET Framework компилируются заранее.

Декомпиляция

Существуют программы, которые решают обратную задачу — перевод программы с низкоуровневого языка на высокоуровневый. Этот процесс называют декомпиляцией, а такие программы — декомпиляторами. Но поскольку компиляция — это процесс с потерями, точно восстановить исходный код, скажем, на C++, в общем случае невозможно. Более эффективно декомпилируются программы в байт-кодах — например, существует довольно надёжный декомпилятор для Flash. Разновидностью декомпилирования является дизассемблирование машинного кода в код на языке ассемблера, который почти всегда выполняется успешно (при этом сложность может представлять самомодифицирующийся код или код, в котором собственно код и данные не разделены). Связано это с тем, что между кодами машинных команд и командами ассемблера имеется практически взаимно-однозначное соответствие.

Раздельная компиляция

Раздельная компиляция (англ. separate compilation) — трансляция частей программы по отдельности с последующим объединением их компоновщиком в единый загрузочный модуль.[2]

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

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

Интересные факты

На заре развития компьютеров первые компиляторы (трансляторы) называли «программирующими программами»[6] (так как в тот момент программой считался только машинный код, а «программирующая программа» была способна из человеческого текста сделать машинный код, то есть запрограммировать ЭВМ).

См. также

  • CORC
  • Компиляторы: принципы, технологии и инструменты
  • SSA

Примечания

  1. ГОСТ 19781-83 // Вычислительная техника. Терминология: Справочное пособие. Выпуск 1 / Рецензент канд. техн. наук Ю. П. Селиванов. — М.: Издательство стандартов, 1989. — 168 с. — 55 000 экз. — ISBN 5-7050-0155-X
  2. 1 2 3 4 5 Першиков В. И., Савинков В. М. Толковый словарь по информатике / Рецензенты: канд. физ.-мат. наук А. С. Марков и д-р физ.-мат. наук И. В. Поттосин. — М.: Финансы и статистика, 1991. — 543 с. — 50 000 экз. — ISBN 5-279-00367-0
  3. 1 2 3 СТ ИСО 2382/7-77 // Вычислительная техника. Терминология. Указ. соч.
  4. Борковский А. Б. Англо-русский словарь по программированию и информатике (с толкованиями). — М.: Русский язык, 1990. — 335 с. — 50 050 (доп,) экз. — ISBN 5-200-01169-3
  5. Толковый словарь по вычислительным системам = Dictionary of Computing / Под ред. В. Иллингуорта и др.: Пер. с англ.
    А. К. Белоцкого и др.; Под ред. Е. К. Масловского. — М.: Машиностроение, 1990. — 560 с. — 70 000 (доп,) экз. — ISBN 5-217-00617-X (СССР), ISBN 0-19-853913-4 (Великобритания)
  6. Н. А. Криницкий, Г. А. Миронов, Г. Д. Фролов. Программирование / Под ред. М. Р. Шура-Бура. — М.: Государственное издательство физико-математической литературы, 1963.

Литература

  • Альфред В. Ахо, Моника С. Лам, Рави Сети, Джеффри Д. Ульман. Компиляторы: принципы, технологии и инструментарий = Compilers: Principles, Techniques, and Tools. — 2-е изд. — М.: Вильямс, 2010. — 1184 с. — ISBN 978-5-8459-1349-4
  • Робин Хантер.
    Основные концепции компиляторов = The Essence of Compilers. — М.: Вильямс, 2002. — 256 с. — ISBN 0-13-727835-7
  • Хантер Р. Проектирование и конструирование компиляторов / Пер. с англ. С. М. Круговой. — М.: Финансы и статистика, 1984. — 232 с.
  • Д. Креншоу. Давайте создадим компилятор!
  • Серебряков В. А., Галочкин М. П. Основы конструирования компиляторов.

Компилятор | это… Что такое Компилятор?

Эта статья включает описание термина «Компиляция»; см. также другие значения.

Компиля́тор — программа или техническое средство, выполняющее компиляцию.[1][2]

[3]

Компиляция — трансляция программы, составленной на исходном языке высокого уровня, в эквивалентную программу на низкоуровневом языке, близком машинному коду (абсолютный код, объектный модуль, иногда на язык ассемблера).[2][3][4] Входной информацией для компилятора (исходный код) является описание алгоритма или программа на проблемно-ориентированном языке, а на выходе компилятора — эквивалентное описание алгоритма на машинно-ориентированном языке (объектный код).[5]

Компилировать — проводить трансляцию машинной программы с проблемно-ориентированного языка на машинно-ориентированный язык.

[3]

Содержание

  • 1 Виды компиляторов[2]
  • 2 Виды компиляции[2]
  • 3 Структура компилятора
  • 4 Генерация кода
    • 4.1 Генерация машинного кода
    • 4.2 Генерация байт-кода
    • 4.3 Динамическая компиляция
    • 4.4 Декомпиляция
  • 5 Раздельная компиляция
  • 6 Интересные факты
  • 7 См. также
  • 8 Примечания
  • 9 Литература

Виды компиляторов

[2]
  • Векторизующий. Транслирует исходный код в машинный код компьютеров, оснащённых векторным процессором.
  • Гибкий. Сконструирован по модульному принципу, управляется таблицами и запрограммирован на языке высокого уровня или реализован с помощью компилятора компиляторов.
  • Диалоговый. См.: диалоговый транслятор.
  • Инкрементальный. Повторно транслирует фрагменты программы и дополнения к ней без перекомпиляции всей программы.
  • Интерпретирующий (пошаговый). Последовательно выполняет независимую компиляцию каждого отдельного оператора (команды) исходной программы.
  • Компилятор компиляторов. Транслятор, воспринимающий формальное описание языка программирования и генерирующий компилятор для этого языка.
  • Отладочный. Устраняет отдельные виды синтаксических ошибок.
  • Резидентный. Постоянно находится в оперативной памяти и доступен для повторного использования многими задачами.
  • Самокомпилируемый. Написан на том же языке, с которого осуществляется трансляция.
  • Универсальный. Основан на формальном описании синтаксиса и семантики входного языка. Составными частями такого компилятора являются: ядро, синтаксический и семантический загрузчики.

Виды компиляции

[2]
  • Пакетная. Компиляция нескольких исходных модулей в одном пункте задания.
  • Построчная. То же, что и интерпретация.
  • Условная. Компиляция, при которой транслируемый текст зависит от условий, заданных в исходной программе директивами компилятора. Так, в зависимости от значения некоторой константы, можно включать или выключать трансляцию части текста программы.

Структура компилятора

Процесс компиляции состоит из следующих этапов:

  1. Лексический анализ. На этом этапе последовательность символов исходного файла преобразуется в последовательность лексем.
  2. Синтаксический (грамматический) анализ. Последовательность лексем преобразуется в дерево разбора.
  3. Семантический анализ. Дерево разбора обрабатывается с целью установления его семантики (смысла) — например, привязка идентификаторов к их декларациям, типам, проверка совместимости, определение типов выражений и т. д. Результат обычно называется «промежуточным представлением/кодом», и может быть дополненным деревом разбора, новым деревом, абстрактным набором команд или чем-то ещё, удобным для дальнейшей обработки.
  4. Оптимизация. Выполняется удаление излишних конструкций и упрощение кода с сохранением его смысла. Оптимизация может быть на разных уровнях и этапах — например, над промежуточным кодом или над конечным машинным кодом.
  5. Генерация кода. Из промежуточного представления порождается код на целевом языке.

В конкретных реализациях компиляторов эти этапы могут быть разделены или, наоборот, совмещены в том или ином виде.

Генерация кода

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

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

Результат компиляции — исполнимый модуль — обладает максимальной возможной производительностью, однако привязан к определённой операционной системе и процессору (и не будет работать на других).

Для каждой целевой машины (IBM, Apple, Sun и т. д.) и каждой операционной системы или семейства операционных систем, работающих на целевой машине, требуется написание своего компилятора. Существуют также так называемые кросс-компиляторы, позволяющие на одной машине и в среде одной ОС генерировать код, предназначенный для выполнения на другой целевой машине и/или в среде другой ОС. Кроме того, компиляторы могут оптимизировать код под разные модели из одного семейства процессоров (путём поддержки специфичных для этих моделей особенностей или расширений наборов инструкций). Например, код, скомпилированный под процессоры семейства Pentium, может учитывать особенности распараллеливания инструкций и использовать их специфичные расширения — MMX, SSE и т. п.

Некоторые компиляторы переводят программу с языка высокого уровня не прямо в машинный код, а на язык ассемблера. Это делается для упрощения части компилятора, отвечающей за кодогенерацию, и повышения его переносимости (задача окончательной генерации кода и привязки его к требуемой целевой платформе перекладывается на ассемблер), либо для возможности контроля и исправления результата компиляции программистом.

Генерация байт-кода

Результатом работы компилятора может быть программа на специально созданном низкоуровневом языке, подлежащем интерпретации виртуальной машиной. Такой язык называется псевдокодом или байт-кодом. Как правило, он не является машинным кодом какого-либо компьютера и программы на нём могут исполняться на различных архитектурах, где имеется соответствующая виртуальная машина, но в некоторых случаях создаются аппаратные платформы, напрямую поддерживающие псевдокод какого-либо языка. Например, псевдокод языка Java называется байт-кодом Java и выполняется в Java Virtual Machine, для его прямого исполнения была создана спецификация процессора picoJava. Для платформы .NET Framework псевдокод называется Common Intermediate Language (CIL), а среда исполнения — Common Language Runtime (CLR).

Некоторые реализации интерпретируемых языков высокого уровня (например, Perl) используют байт-код для оптимизации исполнения: затратные этапы синтаксического анализа и преобразование текста программы в байт-код выполняются один раз при загрузке, затем соответствующий код может многократно использоваться без промежуточных этапов.

Динамическая компиляция

Основная статья: JIT-компиляция

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

CIL-код также компилируется в код целевой машины JIT-компилятором, а библиотеки .NET Framework компилируются заранее.

Декомпиляция

Существуют программы, которые решают обратную задачу — перевод программы с низкоуровневого языка на высокоуровневый. Этот процесс называют декомпиляцией, а такие программы — декомпиляторами. Но поскольку компиляция — это процесс с потерями, точно восстановить исходный код, скажем, на C++, в общем случае невозможно. Более эффективно декомпилируются программы в байт-кодах — например, существует довольно надёжный декомпилятор для Flash. Разновидностью декомпилирования является дизассемблирование машинного кода в код на языке ассемблера, который почти всегда выполняется успешно (при этом сложность может представлять самомодифицирующийся код или код, в котором собственно код и данные не разделены). Связано это с тем, что между кодами машинных команд и командами ассемблера имеется практически взаимно-однозначное соответствие.

Раздельная компиляция

Раздельная компиляция (англ. separate compilation) — трансляция частей программы по отдельности с последующим объединением их компоновщиком в единый загрузочный модуль.[2]

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

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

Интересные факты

На заре развития компьютеров первые компиляторы (трансляторы) называли «программирующими программами»[6] (так как в тот момент программой считался только машинный код, а «программирующая программа» была способна из человеческого текста сделать машинный код, то есть запрограммировать ЭВМ).

См. также

  • CORC
  • Компиляторы: принципы, технологии и инструменты
  • SSA

Примечания

  1. ГОСТ 19781-83 // Вычислительная техника. Терминология: Справочное пособие. Выпуск 1 / Рецензент канд. техн. наук Ю. П. Селиванов. — М.: Издательство стандартов, 1989. — 168 с. — 55 000 экз. — ISBN 5-7050-0155-X
  2. 1 2 3 4 5 Першиков В. И., Савинков В. М. Толковый словарь по информатике / Рецензенты: канд. физ.-мат. наук А. С. Марков и д-р физ.-мат. наук И. В. Поттосин. — М.: Финансы и статистика, 1991. — 543 с. — 50 000 экз. — ISBN 5-279-00367-0
  3. 1 2 3 СТ ИСО 2382/7-77 // Вычислительная техника. Терминология. Указ. соч.
  4. Борковский А. Б. Англо-русский словарь по программированию и информатике (с толкованиями).  — М.: Русский язык, 1990. — 335 с. — 50 050 (доп,) экз. — ISBN 5-200-01169-3
  5. Толковый словарь по вычислительным системам = Dictionary of Computing / Под ред. В. Иллингуорта и др.: Пер. с англ. А. К. Белоцкого и др.; Под ред. Е. К. Масловского. — М.: Машиностроение, 1990. — 560 с. — 70 000 (доп,) экз. — ISBN 5-217-00617-X (СССР), ISBN 0-19-853913-4 (Великобритания)
  6. Н. А. Криницкий, Г. А. Миронов, Г. Д. Фролов. Программирование / Под ред. М. Р. Шура-Бура. — М.: Государственное издательство физико-математической литературы, 1963.

Литература

  • Альфред В. Ахо, Моника С. Лам, Рави Сети, Джеффри Д. Ульман. Компиляторы: принципы, технологии и инструментарий = Compilers: Principles, Techniques, and Tools. — 2-е изд. — М.: Вильямс, 2010. — 1184 с. — ISBN 978-5-8459-1349-4
  • Робин Хантер. Основные концепции компиляторов = The Essence of Compilers. — М.: Вильямс, 2002. — 256 с. — ISBN 0-13-727835-7
  • Хантер Р. Проектирование и конструирование компиляторов / Пер. с англ. С. М. Круговой. — М.: Финансы и статистика, 1984. — 232 с.
  • Д. Креншоу. Давайте создадим компилятор!
  • Серебряков В. А., Галочкин М. П. Основы конструирования компиляторов.

Знакомство с дизайном компилятора — GeeksforGeeks

Компилятор — это программное обеспечение, которое преобразует программу, написанную на языке высокого уровня (исходный язык), в язык низкого уровня (объектный/целевой/машинный язык/0, 1).

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

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

Язык программирования высокого уровня

Язык программирования высокого уровня — это язык, который имеет абстракцию атрибутов компьютера. Программирование высокого уровня более удобно для пользователя при написании программы.

Язык программирования низкого уровня

Язык программирования низкого уровня — это язык, который не требует идей и концепций программирования.

Этапы проектирования компилятора

  1. Лексический анализ: Первым этапом проектирования компилятора является лексический анализ, также известный как сканирование. На этом этапе компилятор считывает исходный код символ за символом и разбивает его на ряд токенов, таких как ключевые слова, идентификаторы и операторы. Затем эти токены передаются на следующий этап процесса компиляции.
  2. Анализ синтаксиса: Вторым этапом разработки компилятора является анализ синтаксиса, также известный как синтаксический анализ. На этом этапе компилятор проверяет синтаксис исходного кода, чтобы убедиться, что он соответствует правилам языка программирования. Компилятор строит дерево синтаксического анализа, которое представляет собой иерархическое представление структуры программы, и использует его для проверки синтаксических ошибок.
  3. Семантический анализ: Третий этап разработки компилятора — семантический анализ. На этом этапе компилятор проверяет смысл исходного кода, чтобы убедиться, что он имеет смысл. Компилятор выполняет проверку типов, что гарантирует правильное использование переменных и выполнение операций над совместимыми типами данных. Компилятор также проверяет наличие других семантических ошибок, таких как необъявленные переменные и некорректные вызовы функций.
  4. Генерация кода: Четвертый этап проектирования компилятора — генерация кода. На этом этапе компилятор переводит дерево синтаксического анализа в машинный код, который может быть выполнен компьютером. Код, сгенерированный компилятором, должен быть эффективным и оптимизированным для целевой платформы.
  5. Оптимизация: Завершающим этапом разработки компилятора является оптимизация. На этом этапе компилятор анализирует сгенерированный код и проводит оптимизацию для повышения его производительности. Компилятор может выполнять такие оптимизации, как свертывание констант, развертывание циклов и встраивание функций.

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

Компилятор

  • Кросс-компилятор , который работает на машине «А» и создает код для другой машины «В». Он способен создавать код для платформы, отличной от той, на которой работает компилятор.
  • Компилятор исходного кода или транскомпилятор или транспайлер — это компилятор, который переводит исходный код, написанный на одном языке программирования, в исходный код другого языка программирования.

Системы обработки речи

Мы знаем, что компьютер представляет собой логическую сборку программного и аппаратного обеспечения. Аппаратное обеспечение знает язык, который нам трудно понять, следовательно, мы склонны писать программы на языке высокого уровня, который нам гораздо легче понять и поддерживать в уме. Теперь эти программы претерпевают ряд преобразований, чтобы их можно было легко использовать на машинах. Здесь на помощь приходят системы языковых процедур.

Язык высокого уровня для машинного кода

  • Язык высокого уровня: Если программа содержит директивы #define или #include, такие как #include или #define, она называется HLL. Они ближе к людям, но далеки от машин. Эти теги (#) называются директивами препроцессора. Они указывают препроцессору, что делать.
  • Препроцессор: Препроцессор удаляет все директивы #include, включая файлы, называемые включением файлов, и все директивы #define, использующие раскрытие макросов. Он выполняет включение файлов, увеличение, макрообработку и т. д.
  • Язык ассемблера: Не в бинарной форме и не на высоком уровне. Это промежуточное состояние, представляющее собой комбинацию машинных инструкций и некоторых других полезных данных, необходимых для выполнения.
  • Ассемблер: Для каждой платформы (Оборудование + ОС) у нас будет ассемблер. Они не универсальны, так как для каждой платформы у нас есть своя. Результат работы ассемблера называется объектным файлом. Он переводит язык ассемблера в машинный код.
  • Переводчик: Интерпретатор преобразует язык высокого уровня в машинный язык низкого уровня, как компилятор. Но они отличаются тем, как они читают ввод. Компилятор за один раз считывает входные данные, выполняет обработку и выполняет исходный код, тогда как интерпретатор делает то же самое построчно. Компилятор сканирует всю программу и переводит ее целиком в машинный код, тогда как интерпретатор переводит программу по одному оператору за раз. Интерпретируемые программы обычно медленнее скомпилированных. Например: Пусть в исходнике программы написано #include «Stdio. час». Препроцессор заменяет этот файл своим содержимым в произведенном выводе. Основная работа компоновщика заключается в объединении кодов объектов (которые даже не были соединены), созданных компилятором, ассемблером, стандартной библиотечной функцией и ресурсами операционной системы. Коды, сгенерированные компилятором, ассемблером и компоновщиком, обычно перемещаются по своей природе, то есть начальное местоположение этих кодов не определено, а значит, они могут находиться где угодно в памяти компьютера. Таким образом, основная задача загрузчиков, чтобы найти/вычислить точный адрес этих ячеек памяти.
  • Перемещаемая машина Код: Она может быть загружена в любой момент и может быть запущена. Адрес внутри программы будет таким, чтобы он сотрудничал с движением программы.
  • Загрузчик/компоновщик: Загрузчик/компоновщик преобразует перемещаемый код в абсолютный код и пытается запустить программу, что приводит к запуску программы или сообщению об ошибке (иногда может произойти и то, и другое). Компоновщик загружает различные объектные файлы в один файл, чтобы сделать его исполняемым. Затем загрузчик загружает его в память и выполняет.

Типы компиляторов

В основном существует три типа компиляторов.

  • Однопроходные компиляторы
  • Двухпроходные компиляторы
  • Многопроходные компиляторы

Однопроходные компиляторы

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

Двухпроходный компилятор

Двухпроходный компилятор — это компилятор, в котором программа транслируется дважды, один раз из внешнего интерфейса и один раз из внутреннего, известный как двухпроходный компилятор.

Многопроходный компилятор

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

Фазы компилятора

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

Фазы компилятора

Фаза анализа

Промежуточное представление создается из данного исходного кода: 

  • Лексический анализатор
  • Синтаксический анализатор
  • Семантический анализатор
  • Генератор промежуточного кода
9000 2 Лексический анализатор разбивает программу на «лексемы», синтаксический анализатор распознает «предложения» в программе с использованием синтаксиса языка, а семантический анализатор проверяет статическую семантику каждой конструкции. Intermediate Code Generator генерирует «абстрактный» код.

Фаза синтеза

Эквивалентная целевая программа создается из промежуточного представления. Он состоит из двух частей:

  • Оптимизатор кода
  • Генератор кода

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

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

Это некоторые операции, выполняемые компилятором.

  • Разбивает исходные программы на более мелкие части.
  • Позволяет создавать таблицы символов и промежуточные представления.
  • Помогает в компиляции кода и обнаружении ошибок.
  • сохраняет все коды и переменные.
  • Анализирует всю программу и переводит ее.
  • Преобразование исходного кода в машинный код.

Преимущества конструкции компилятора

  1. Эффективность: Скомпилированные программы, как правило, более эффективны, чем интерпретируемые программы, потому что машинный код, созданный компилятором, оптимизирован для конкретной аппаратной платформы, на которой он будет работать.
  2. Переносимость: После того как программа скомпилирована, полученный машинный код может быть запущен на любом компьютере или устройстве с соответствующим оборудованием и операционной системой, что делает ее очень переносимой.
  3. Проверка ошибок: Компиляторы выполняют всестороннюю проверку ошибок в процессе компиляции, что может помочь выявить синтаксические, семантические и логические ошибки в коде до его запуска.
  4. Оптимизации: Компиляторы могут выполнять различные оптимизации сгенерированного машинного кода, такие как удаление избыточных инструкций или изменение кода для повышения производительности.

Недостатки разработки компилятора

  1. Более длительное время разработки: Разработка компилятора — сложный и трудоемкий процесс, требующий глубокого понимания как языка программирования, так и целевой аппаратной платформы.
  2. Трудности при отладке: Отладка скомпилированного кода может оказаться более сложной задачей, чем отладка интерпретируемого кода, поскольку сгенерированный машинный код может оказаться трудным для чтения или понимания.
  3. Отсутствие интерактивности: Скомпилированные программы обычно менее интерактивны, чем интерпретируемые программы, потому что они должны быть скомпилированы перед запуском, что может замедлить процесс разработки и тестирования.
  4. Код для конкретной платформы: Если компилятор предназначен для генерации машинного кода для конкретной аппаратной платформы, полученный код может оказаться непереносимым на другие платформы.

Угловые вопросы GATE CS

Ответы на следующие вопросы помогут вам проверить свои знания. Все вопросы были заданы в GATE в предыдущие годы или в пробных тестах GATE. Настоятельно рекомендуется их практиковать.

  1. GATE CS 2011, Вопрос 1
  2. GATE CS 2011, Вопрос 19
  3. GATE CS 2009, Вопрос 17
  4. GATE CS 1998, Вопрос 27
  5. GATE CS 2008, Вопрос 85
  6. GATE CS 1997, Вопрос 8
  7. GATE CS 2014 (набор 3), вопрос 65
  8. GATE CS 2015 (набор 2), вопрос 29

Что такое компилятор? | Codementor

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

В этой статье мы рассмотрим различные типы компиляторов, доступные сегодня. Мы также обсудим, почему использование компилятора выгодно при разработке программного обеспечения, включая его плюсы и минусы, а также примеры из реального мира.

Что такое компилятор?

Компилятор — это программа, преобразующая исходный код в машинный код. Затем эта программа используется для генерации машинного кода, который можно использовать для запуска программы. Компилятор можно использовать для перевода исходного кода, написанного на разных языках программирования, включая C, C++ и Java.
Основная цель компилятора — обеспечить корректность исходного кода и простоту понимания программы. Компилятор также помогает гарантировать, что сгенерированный машинный код корректен и оптимизирован для используемого оборудования. Компилятор можно использовать для самых разных целей, включая обнаружение ошибок и оптимизацию. Например, компилятор можно использовать для обнаружения ошибок в исходном коде и оптимизации сгенерированного машинного кода для повышения производительности или эффективности.

Типы компиляторов:

Компиляторы можно разделить на несколько категорий:

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

Компилятор исходного кода: Компилятор исходного кода — это программный инструмент, который переводит исходный код в исполняемый код. Инструмент полезен для перевода исходного кода, написанного на разных языках программирования. Процесс перевода обычно выполняется компилятором, который переводит исходный код в машинный код определенного типа. Сгенерированный машинный код затем выполняется на целевой машине. Процесс перевода может быть выполнен вручную или автоматически. Программный инструмент можно использовать для перевода исходного кода, написанного на разных языках программирования, таких как C++, Java и C#.

Компилятор Just-in-time (JIT): Компилятор Just-in-time (JIT) — это компилятор, предназначенный для компиляции программ по мере их выполнения. Это делает компилятор намного быстрее, чем традиционный компилятор, который должен компилировать программу с нуля каждый раз, когда она запускается. Основное преимущество компилятора JIT заключается в том, что он позволяет уменьшить размер вашей программы за счет устранения избыточного кода. Это означает, что ваша программа будет меньше и эффективнее. Еще одним преимуществом JIT-компилятора является то, что он может оптимизировать вашу программу для разных платформ. Например, если вы разрабатываете мобильное приложение, вы можете использовать JIT-компилятор для оптимизации кода под разные устройства. Компилятор JIT также имеет много других преимуществ, таких как сокращение использования памяти, повышение производительности и повышение надежности.

Компиляторы байт-кода: Компилятор байт-кода — это программный инструмент, который переводит язык высокого уровня (например, Java) в машинный код. Полученный код затем компилируется в машинный код, который может выполняться на целевой машине. Основное преимущество компиляторов байт-кода заключается в том, что они позволяют разработчикам писать код на языке высокого уровня, а затем компилировать его в машинный код. Это позволяет разработчикам писать более лаконичный и понятный код. Основным недостатком компиляторов байт-кода является то, что они должны быть написаны на языке высокого уровня. Это означает, что они не подходят для разработки низкоуровневого кода. Компиляторы байт-кода чаще всего используются при разработке мобильных приложений.

Аппаратные компиляторы: Аппаратные компиляторы — это программные инструменты, которые компилируют исходный код в машинный код. Они используются для преобразования исходного кода в машинный код, который затем выполняется компьютером. Они используются в самых разных приложениях, включая компьютерные игры, встроенные системы и операционные системы. Наиболее распространенным типом аппаратного компилятора является ассемблер. Он преобразует исходный код в машинный код, который затем выполняется компьютером. Ассемблер обычно пишется на языке высокого уровня (например, C или C++) и используется для сборки программ, написанных на языках низкого уровня (например, на языке ассемблера). Другие типы аппаратных компиляторов включают компоновщик, который переводит исходный код в машинный код; и загрузчик, который переводит машинный код в исходный код. Компоновщик и загрузчик используются для создания динамических компоновщиков, которые позволяют связывать программы друг с другом. Аппаратные компиляторы часто используются для преобразования исходного кода в машинный код. Этот процесс перевода называется компиляцией. Компиляция преобразует исходный код в машинный код, который затем выполняется компьютером. Компилятор обычно пишется на языке высокого уровня (например, C или C++) и используется для компиляции программ, написанных на языках низкого уровня (например, на языке ассемблера).

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

Как работает компилятор?

Компиляторы используют разные подходы к преобразованию кода в вывод, несмотря на их различия. Обычно они выполняют следующие шаги:

  1. Лексический анализ — это процесс токенизации кода, чтобы сделать его синтаксическим и семантическим.
  2. Во время синтаксического анализа компилятор создает абстрактные синтаксические деревья, отображающие логические структуры определенных элементов кода. Эти деревья известны как синтаксические деревья.
  3. Проверка семантической правильности логики кода зависит от семантического анализа. Например, можно проверить тип или определение переменной, чтобы убедиться, что им присвоены правильные типы или они правильно определены.
  4. Промежуточный код, сгенерированный после того, как код проходит через все три этапа анализа, называется IR-кодом. Легче преобразовать код в другой формат, используя код IR, а не новый код. Тем не менее, он должен быть точным во всех отношениях, включая упущение какой-либо функциональности.
  5. Оптимизация выполняется в рамках подготовки к окончательной генерации кода на оптимизированном компилятором IR-коде с целью экономии процессорного времени. Некоторые компиляторы допускают настройку степени оптимизации.
  6. Код создается компилятором с использованием оптимизированного кода IR.

Применение компилятора:

  1. Разработка компиляторов помогает полностью реализовать языки программирования высокого уровня.
  2. Чтобы улучшить архитектуру параллельных компьютеров, поддержите оптимизацию.
  3. Разработка новых иерархий памяти машин.
  4. Используется для перевода программ.
  5. В дополнение к Программному обеспечению должны использоваться другие средства повышения производительности программного обеспечения.

Чем компилятор отличается от интерпретатора?

  1. Компилятор программы сразу ищет ошибки программы. При обнаружении ошибки программа останавливается. Интерпретатор проверяет каждую строку кода по отдельности.
  2. Оператор программы высокого уровня кодируется с помощью интерпретатора или компилятора в машинный код. Напротив, интерпретатор преобразует высокоуровневую программу в машинный код, а компилятор преобразует код перед запуском программы.
  3. Компиляторы преобразуют языки программирования в машинный код во время работы программы, а не в интерпретируемые языки. С другой стороны, интерпретаторы преобразуют каждое выражение отдельно в машинный код по мере выполнения программы.
  4. Скомпилированный код выполняется быстрее интерпретируемого кода.
    5. Компилятор основан на методологии загрузки-связывания перевода, а интерпретатор основан на методе интерпретации.
    Подробнее о разнице между компилятором и интерпретатором читайте на Interviewbit.