что это такое и как применяется в программировании

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

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

Языки программирования, для перевода которых используются компиляторы, называются компилируемыми.

Для чего нужен компилятор

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

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

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

Компилятор и интерпретатор: в чем разница

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

Интерпретатор — это тоже программа, которая «переводит» текст на высокоуровневом языке программирования, но делает это иначе. Она не собирает весь код в один исполняемый файл для последующего запуска, а исполняет код сразу, построчно. Это чуть медленнее, но иногда удобнее. Языки, использующие интерпретаторы, называются интерпретируемыми.

Байт-код — «промежуточное звено» между подходами компиляции и интерпретации. Программа преобразуется в особый код, который запускается под специальной виртуальной машиной. Языков, которые работают так, относительно немного, самый известный и яркий пример — Java.

В каких языках используются компиляторы

Среди популярных сегодня языков компилируемыми являются Swift и Go, а также C / C++ и Objective-C. Другие примеры — Visual Basic, Haskell, Pascal / Delphi, Rust, а также Lisp, Prolog и прочие менее известные языки. Разумеется, компилируемым является и язык ассемблера — очень низкоуровневый и написанный напрямую на машинных кодах.

Отдельно можно выделить языки, которые трансформируются в байт-код — это тоже своего рода компиляция. К ним относятся Java, Scala и Kotlin, а также C# и языки платформы .NET.

На каких языках пишут компиляторы

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

Например, один из компиляторов языка Go частично написан на C++, самый первый компилятор C++ — на ассемблере, а уже ассемблер — на машинных кодах.

Тот же язык. Написать компилятор для языка программирования можно на других версиях того же языка — такой подход разрешен и активно используется в разработке. Это нужно, чтобы компиляторы были более гибкими и «умными» и могли поддерживать больше возможностей, — ассемблер довольно примитивен и не решает всех задач.

Выглядит это так:

  • первый, более простой компилятор пишется на ассемблере;
  • второй пишется уже на нужном языке и компилируется первым компилятором;
  • переведенный в машинные коды второй компилятор компилирует свои же исходники — получается более новая и мощная версия его же.

Например, большинство современных компиляторов для C / C++ написано на C / C++. Такие компиляторы называют самокомпилируемыми.

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

У большинства языков программирования несколько компиляторов. Их еще называют реализациями. Изначальную реализацию пишет создатель языка, потом со временем появляются альтернативные. Зачем это делается? Цели могут быть разными:

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

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

Какими бывают компиляторы

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

Один компилятор может «знать» несколько языков программирования. Яркий пример такого решения — GCC, или GNU Compiler Collection, кросс-компилятор для нескольких операционных систем и языков, полностью бесплатный и свободный. На нем написано программное обеспечение GNU.

Существуют и так называемые компиляторы компиляторов. Они генерируют компиляторы для языка на основе его формального описания.

Как устроены и работают компиляторы

Простыми словами, они «читают» пришедшую к ним на вход программу и переводят ее команды в соответствующие им наборы машинных кодов.

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

Сама компиляция может быть:

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

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

Преимущества компилируемых языков
  • Компилируемые языки обычно быстрее, чем интерпретируемые, и их легче оптимизировать.
  • Итоговый размер кода у компилируемых языков, как правило, меньше, чем у интерпретируемых.
  • В компилируемых языках намного шире возможность контролировать аппаратные ресурсы. Это не значит, что они все низкоуровневые, но обратное — верно: практически все низкоуровневые языки — компилируемые.
  • Когда процессоры становятся мощнее, именно компилируемые языки могут в должной мере задействовать их преимущества.
  • Код после компилятора лучше оптимизируется под конкретные устройства, архитектуру «железа», эффективно задействует память и не тратит лишних ресурсов.
  • Компилируемые языки обычно мощные и высокопроизводительные, поэтому на них пишут игры и другие серьезно нагруженные приложения.

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

Как пользоваться компилятором

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

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

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

Узнайте больше об устройстве и работе языков программирования на курсах — получите новую профессию и станьте востребованным IT-специалистом.

Компиляция программы на python 3 в exe с помощью программы cx_Freeze

Наверняка, у каждого Python-программиста возникало непреодолимое желание, а изредка и реальная потребность, скомпилировать свою программу на python в exe файл. Сегодня я расскажу, как это сделать с помощью программы cx_Freeze.

Вопрос 1: а оно надо?

Прежде, чем начинать компилировать программу, нужно убедиться, что это действительно необходимо.

«Компиляция» программы на python — процесс, который может сопровождаться множеством проблем. Более того, это не компиляция в машинный код, как, например, программы на C, а лишь «сборка» в исполняемый файл вашей программы вместе с частью интерпретатора python.

Поэтому, если вы будете использовать программу сами или на компьютерах тех, кто её будет использовать, будет стоять интерпретатор python, то вам не нужно её компилировать.

Установка cx_Freeze

Если компилировать программу на python всё-таки нужно, то скачиваем cx_Freeze с http://www.lfd.uci.edu/~gohlke/pythonlibs/#cx_freeze (так как в ней нет одного неприятного бага, который есть в официальной версии).

Затем устанавливаем, не забывая правильно выбрать директорию, где расположен python.

Компиляция

Компилировать будем программу «блэкджек» (файл 21.py) (кому лень смотреть, привожу полный исходный код).

import random
random.shuffle(koloda)
print('Поиграем в очко?')
count = 0
while True:
    choice = input('Будете брать карту? y/n\n')
    if choice == 'y':
        current = koloda. pop()
        print('Вам попалась карта достоинством %d' %current)
        count += current
        if count > 21:
            print('Извините, но вы проиграли')
            break
        elif count == 21:
            print('Поздравляю, вы набрали 21!')
            break
        else:
            print('У вас %d очков.' %count)
    elif choice == 'n':
        print('У вас %d очков и вы закончили игру.' %count)
        break
print('До новых встреч!')

Создаём в папке с программой файл setup.py с содержимым:

from cx_Freeze import setup, Executable
setup(
    name = "21",
    version = "0.1",
    description = "Blackjack",
    executables = [Executable("21.py")]
)

Переходим в командную строку (обычно Пуск → Стандартные → Командная строка). Переходим в папку с программой (в моём случае D:\Dima\py). Запускаем команду C:\Python34\python.exe setup.py build (вместо C:\Python34 нужно написать папку, куда установлен python).

Начнется процесс сборки, в котором cx_Freeze может выдавать предупреждения, но, скорее всего, они не повлияют на работу программы.

Поздравляю! В папке build теперь есть ваша папка с исполняемым файлом!

Заметьте, не файл, а папка! Все остальные файлы также нужны для работы программы (да, это недостаток cx_Freeze). К тому же, при завершении программы окно сразу закрывается (а не ждет нажатия клавиши), поэтому в конец программы нужно дописать что-то вроде:

input("Press Enter")

И скомпилировать ещё раз.

Также можно создать msi-архив командой C:\Python34\python.exe setup.py bdist_msi.

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

Для их решения следует воспользоваться официальной документацией.

Для вставки кода на Python в комментарий заключайте его в теги <pre><code>Ваш код</code></pre>

Свежее

  • Модуль csv — чтение и запись CSV файлов
  • Создаём сайт на Django, используя хорошие практики. Часть 1: создаём проект
  • Онлайн-обучение Python: сравнение популярных программ

Категории

  • Книги о Python
  • GUI (графический интерфейс пользователя)
  • Курсы Python
  • Модули
  • Новости мира Python
  • NumPy
  • Обработка данных
  • Основы программирования
  • Примеры программ
  • Типы данных в Python
  • Видео
  • Python для Web
  • Работа для Python-программистов

Полезные материалы

  • Сделай свой вклад в развитие сайта!
  • Самоучитель Python
  • Карта сайта
  • Отзывы на книги по Python
  • Реклама на сайте

Мы в соцсетях

Компиляция программы на C: за кулисами

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

Как скомпилировать и запустить программу на C?
Ниже приведены шаги, которые мы используем на машине Ubuntu с компилятором gcc.

  • Сначала мы создаем программу на C с помощью редактора и сохраняем файл как имя_файла.c
  $ vi имя_файла.c  
  • На схеме справа показана простая программа для сложения двух чисел.

  • Затем скомпилируйте его, используя команду ниже.
  $ gcc -Wall имя_файла.c –o имя_файла  
  • Параметр -Wall включает все предупреждающие сообщения компилятора. Этот вариант рекомендуется для создания лучшего кода.
    Параметр -o используется для указания имени выходного файла. Если мы не используем эту опцию, то создается выходной файл с именем a.out.

  • После создания исполняемого файла компиляции мы запускаем сгенерированный исполняемый файл с помощью приведенной ниже команды.
  $ ./filename  

Что происходит внутри процесса компиляции?
Компилятор преобразует программу C в исполняемый файл. Существует четыре этапа превращения программы C в исполняемый файл:

  1. Предварительная обработка
  2. Компиляция
  3. Сборка
  4. Связывание

Выполняя приведенную ниже команду, мы получаем все промежуточные файлы в текущем каталоге вместе с исполняемым файлом. .

  $gcc -Wall -save-temps имя_файла.c –o имя_файла  

На следующем снимке экрана показаны все сгенерированные промежуточные файлы.

Давайте последовательно посмотрим, что содержат эти промежуточные файлы.

Предварительная обработка

Это первая фаза, через которую проходит исходный код. Этот этап включает:  

  • Удаление комментариев
  • Расширение макросов
  • Расширение включенных файлов.
  • Условная компиляция

Предварительно обработанный вывод сохраняется в файле имя_файла.i . Давайте посмотрим, что находится внутри filename.i: using $vi filename.i   
В приведенном выше выводе исходный файл заполнен большим количеством информации, но в конце наш код сохраняется.
Анализ:  

  • printf теперь содержит a + b, а не add(a, b), потому что макросы расширились.
  • Комментарии удалены.
  • #include отсутствует, вместо этого мы видим много кода. Итак, файлы заголовков были расширены и включены в наш исходный файл.

Компиляция

Следующим шагом является компиляция filename.i и создание файла; промежуточный скомпилированный выходной файл filename.s . Этот файл находится в инструкциях уровня сборки. Давайте посмотрим на этот файл, используя $vi filename.s  

Снимок показывает, что он написан на языке ассемблера, который ассемблер понимает.

Сборка
На этом этапе имя файла.s берется в качестве входных данных и преобразуется ассемблером в имя_файла.o . Этот файл содержит инструкции машинного уровня. На этом этапе только существующий код преобразуется в машинный язык, вызовы функций, таких как printf(), не разрешаются. Давайте просмотрим этот файл, используя $vi filename.o  

 

Связывание

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

Обратите внимание, что GCC по умолчанию выполняет динамическую компоновку, поэтому printf() динамически компонуется в приведенной выше программе. Обратитесь к этому, этому и этому для получения более подробной информации о статических и динамических ссылках.
Эта статья предоставлена ​​ Викашем Кумаром . Пожалуйста, пишите комментарии, если вы обнаружите что-то неправильное, или вы хотите поделиться дополнительной информацией по теме, обсуждаемой выше.

Процесс компиляции CICS (COBOL + CICS)

  • Что может прекомпилятор?
  • Что может транслятор CICS?
  • Что может компилятор?
  • Что может редактор связей?

В настоящее время наиболее часто используемыми технологиями в прикладных программах CICS являются COBOL, CICS и DB2.

Такие технологии, как IMS DB/DC, очень редко используются в старых проектах, которые не перенесены на DB2.

Итак, в этой главе мы обсудим процесс компиляции прикладной программы COBOL CICS DB2.

Прежде чем приступить к процессу компиляции CICS COBOL DB2, выполните здесь процесс предварительной компиляции COBOL DB2 , чтобы получить общее представление о процессе компиляции.

Помимо процесса предварительной компиляции, к компиляции добавлен еще один дополнительный шаг, который называется «трансляция CICS» для прикладной программы CICS с помощью COBOL CICS DB2.

На приведенной ниже диаграмме показаны этапы процесса компиляции CICS –

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

Прекомпилятор отделяет операторы DB2 от операторов других языков исходной программы. Операторы DB2 должны быть закодированы со встроенными операторами SQL (EXEC SQL) для распознавания прекомпилятором, поскольку большинство компиляторов не распознают операторы SQL.

Прекомпилятор DB2 должен быть закодирован до этапа компиляции программы, чтобы предотвратить ошибки компилятора. Прекомпилятор DB2 преобразует команды EXEC SQL в комментарии и генерирует соответствующие операторы CALL.

Прекомпилятор сканирует программу и возвращает измененный исходный код. Прекомпилятор DB2 отделяет операторы SQL от языков C, COBOL, Fortran, PL/I и ассемблера перед компиляцией.

Основным выходом прекомпилятора является модуль запросов к базе данных (DBRM). DBRM — это набор данных, который содержит операторы SQL и информацию о переменных хоста, извлекаемую из исходной программы во время предварительной компиляции программы. Целью DBRM является передача запросов SQL в DB2 во время процесса связывания.

Что может переводчик CICS?

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

Встроенный транслятор преобразует команды EXEC CICS в комментарии и генерирует операторы CALL, соответствующие языку. Версии встроенного транслятора доступны для языков — C, C++, COBOL и PL/I.

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

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

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

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

Компиляция — это важный процесс преобразования кода программы высокого уровня (COBOL) в код низкого уровня. Код языка низкого уровня — это язык машинного уровня, который может понять только машина.

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

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

Что может редактор связей?

Редактор компоновки связывает объектную программу с любыми вызываемыми из нее подпрограммами, а также создает исполняемый компонент для программы. Редактор компоновки, создающий исполняемый компонент программы, называемый загрузочным модулем.

Редактор связей связывает объектную программу с одной или несколькими системными подпрограммами. Однако он также может связать его с подпрограммами COBOL. Шаг редактирования ссылки принимает модуль объекта, созданный на этапе компиляции, в качестве входных данных, и ссылка редактирует его для создания окончательного файла загрузки.