Компилируемые и интерпретируемые языки программирования. Разбор понятий


Deprecated: Function eregi_replace() is deprecated in /hlds/web/u138079p19/code4life.ru/htdocs/wp-content/plugins/wp-note/wp-note.php on line 43

Deprecated: Function eregi_replace() is deprecated in /hlds/web/u138079p19/code4life.ru/htdocs/wp-content/plugins/wp-note/wp-note.php on line 43

Deprecated: Function eregi_replace() is deprecated in /hlds/web/u138079p19/code4life.ru/htdocs/wp-content/plugins/wp-note/wp-note.php on line 43

Deprecated: Function eregi_replace() is deprecated in /hlds/web/u138079p19/code4life.ru/htdocs/wp-content/plugins/wp-note/wp-note.php on line 43

Deprecated: Function eregi_replace() is deprecated in /hlds/web/u138079p19/code4life.ru/htdocs/wp-content/plugins/wp-note/wp-note.php on line 43

Deprecated: Function eregi_replace() is deprecated in /hlds/web/u138079p19/code4life.ru/htdocs/wp-content/plugins/wp-note/wp-note.php on line 43

Deprecated: Function eregi_replace() is deprecated in /hlds/web/u138079p19/code4life.ru/htdocs/wp-content/plugins/wp-note/wp-note.php on line 43

Deprecated: Function eregi_replace() is deprecated in /hlds/web/u138079p19/code4life.ru/htdocs/wp-content/plugins/wp-note/wp-note.php on line 43

Deprecated: Function eregi_replace() is deprecated in /hlds/web/u138079p19/code4life.ru/htdocs/wp-content/plugins/wp-note/wp-note.php on line 43

Deprecated: Function eregi_replace() is deprecated in /hlds/web/u138079p19/code4life.ru/htdocs/wp-content/plugins/wp-note/wp-note.php on line 43

Notice: Функция get_currentuserinfo с версии 4.5.0 считается устаревшей! Используйте wp_get_current_user(). in /hlds/web/u138079p19/code4life.ru/htdocs/wp-includes/functions.php on line 3840

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

И вот перед выпуском s4g пообщавшись с товарищем … решил поставить под сомнение свое понимание этих понятий и безотносительно выяснить что это все значит, и как оказалось совсем не зря, потом что даже вики говорит о размытости границ между этими понятиями:

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

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

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

Теперь необходимо понять что такое компиляция, опять обращаемся к вики:

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

Результатом работы компилятора может быть программа на специально созданном низкоуровневом языке, подлежащем интерпретации виртуальной машиной. Такой язык называется псевдокодом или байт-кодом.

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

Разберем теперь понятие интерпретация, опять же обращаемся к вики:

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

А что такое интерпретация касаемо языков программирования:

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

Казалось бы … теперь все понятно, но сомнения все-таки остались. Ну а как же тогда точно расставить все по местам? Ведь даже при таком раскладе получается что практически для любого языка можно написать интерпретатор?

Тогда вот еще информация с вики:

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

  1. Лексический анализ

  2. Синтаксический анализ

  3. Оптимизация

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

Все-равно мало …

Обратимся еще раз к понятию интерпретация: совокупность значений, придаваемых тем или иным способом элементам  какой-либо естественнонаучной или абстрактно-дедуктивной теории. Значит ли это что интерпретация это одна итерация?

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

  • сначала на вход поступает поток символов (исходный код), который разбивается на лексемы, то есть первая итерация интерпретации — делаем понятным поток символом для синтаксического анализатора (интерпретируем для парсера);
  • на этапе синтаксического анализа строим абстрактное синтаксическое дерево (АСТ), то есть вторая итерация — делаем понятными лексемы (не исходный код) для генератора кода (интерпретируем для генератора кода);
  • на этапе генерации кода преобразуем АСТ в код (машинный либо байт-код), то есть третья итерация — делаем понятным АСТ (не лексемы и уж тем более не исходный код) для машины (реальной либо виртуальной) (интерпретация для машины), итог — код.

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

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

Таким образом любой язык имеющий более одной итерации интерпретации будет являться компилируемым. Либо любой такой язык можно назвать языком с определенным количеством интерпретаций, потому что название такому языку «интерпретируемый» будет как минимум не полное описание его типа восприятия.

Ладно, определились, но что тогда в таком случае будет являться интерпретируемым языком программирования? Судя по всему, таковым языком будет тот язык, который имеет только одну итерацию интерпретации. Утверждать не буду, но ИМХО, такой язык лишен высокоуровневости, и будет представлять из себя нечто вроде:

push 10
push 5
add

То есть некое подобие ассемблера, похожего на байт-код виртуальной машины))

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


Часто скриптовые языки называют интерпретируемыми еще и потому что генератор кода в них называется компилятором, это конечно же не верно, и мы сами неверно назвали в s4g 0.9.2 генератор кода компилятором. Компилятор это нечто большее чем простая интерпретация АСТ в байт-код. В следующих версиях будем исправляться))

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

Если уж компилируемый язык компилируется в машинный код … тогда он будет исполнятся как на Windows так и на Linux с аналогичным железом?))


Итак, запрепим:

Интепретатор — программа исполняющая исходный код пооператорно (построчно, по командно).

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

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

Поделиться:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*