Нет такой вещи, как «скомпилированный язык» или «интерпретируемый язык» - PullRequest
15 голосов
/ 09 августа 2010

"Не существует такого понятия, как" скомпилированный язык "или" интерпретируемый язык ". Независимо от того, выберет ли разработчик языка написать компилятор, интерпретатор или что-то среднее, это деталь реализации и не имеет ничего общего с языком."

Верно ли приведенное выше утверждение?

Ответы [ 8 ]

14 голосов
/ 09 августа 2010

Да, это так в самой строгой интерпретации.Например, вы можете найти интерпретатор C ++ и Javascript compiler .Однако вы обнаружите, что некоторые типы языков (например, статически типизированные) хорошо поддаются компиляции нативного кода.Другие языки (например, динамически типизированные) обычно реализуются с использованием компиляции байт-кода в сочетании со средой исполнения виртуальной машины.

3 голосов
/ 09 августа 2010

Вроде. Как правило, и интерпретаторы, и компиляторы сначала должны проанализировать исходный код и превратить его в представление, называемое AST (абстрактное синтаксическое дерево). Затем компилятор превращает AST в исполняемый код (посредством различных преобразований), в то время как интерпретатор может просто «интерпретировать» AST или иногда компилировать и выполнять его (компиляция точно в срок).

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

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

1 голос
/ 09 августа 2010

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

Между ними есть абстрактное синтаксическое дерево.

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

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

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

Это не совсем правильно, если мы говорим о генераторе кода.

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

Так что, возможно, именно так размыто различие.Но я думаю, что это все еще там.

0 голосов
/ 09 августа 2010

Стоит отметить, что для (некоторых?) Языков, которые включают оператор типа «eval» (особенно, если до времени выполнения невозможно определить, является ли данный блок кодом или данными), даже самая чисто скомпилированная версия данная программа должна быть частично интерпретирована. Для таких языков невозможно скомпилировать их полностью (скомпилированный код должен содержать интерпретатор языка).

В качестве примера рассмотрим следующий код:

set s [eval {sum $a $b $c}]

Для приведенного выше кода Tcl невозможно до времени выполнения определить, является ли блок (внутри {}) кодом или нет.

0 голосов
/ 09 августа 2010

Все дело в компиляторе / интерпретаторе зависит от ваших намерений в отношении вашей программы. Скомпилированная программа превращается в машинный код. Переводчик используется для чтения языка-посредника и запуска его на компьютере. Например, когда вы компилируете Java, он превращается в байт-код Java и читается и запускается интерпретатором (что также объясняет недостаток скорости по сравнению с C ++).

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

0 голосов
/ 09 августа 2010

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

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

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

0 голосов
/ 09 августа 2010

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

0 голосов
/ 09 августа 2010

Вышеприведенное утверждение верно.

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

...