Краткое изложение, которое я даю ниже, основано на «Компиляторах, принципах, методах и инструментах», Aho, Lam, Sethi, Ullman (Pearson International Edition, 2007), страницы 1, 2, с добавлением некоторых моих собственных идей.
Два основных механизма обработки программы - это компиляция и интерпретация .
Компиляция принимает в качестве входных данных исходную программу на заданном языке и выводит целевую программу на целевом языке.
source program --> | compiler | --> target program
Если целевой язык - машинный код, он может быть выполнен непосредственно на некотором процессоре:
input --> | target program | --> output
Компиляция включает в себя сканирование и перевод всей входной программы (или модуля) и не требует ее выполнения.
Интерпретация принимает в качестве входных данных исходную программу и ее входные данные и производит выходные данные исходной программы
source program, input --> | interpreter | --> output
Интерпретация обычно включает обработку (анализ и выполнение) программы по одному утверждению за раз.
На практике многие языковые процессоры используют сочетание двух подходов. Например, Java-программы сначала переводятся (компилируются) в промежуточную программу (байт-код):
source program --> | translator | --> intermediate program
выходные данные этого шага затем выполняются (интерпретируются) виртуальной машиной:
intermediate program + input --> | virtual machine | --> output
Чтобы усложнить ситуацию еще больше, JVM может выполнить компиляцию точно в срок во время выполнения для преобразования байтового кода в другой формат, который затем выполняется.
Кроме того, даже когда вы компилируете в машинный язык, есть интерпретатор, запускающий ваш двоичный файл, который реализован базовым процессором. Поэтому даже в этом случае вы используете гибрид компиляции + интерпретации.
Таким образом, в реальных системах используется сочетание этих двух факторов, поэтому трудно сказать, является ли данный языковой процессор компилятором или интерпретатором, поскольку он, вероятно, будет использовать оба механизма на разных этапах своей обработки. В этом случае, вероятно, было бы более целесообразно использовать другой, более нейтральный термин.
Тем не менее, компиляция и интерпретация являются двумя различными видами обработки, как описано на диаграммах выше,
Чтобы ответить на первоначальные вопросы.
Компилятор будет создавать машинный язык, который работает на физическом оборудовании напрямую?
Необязательно, компилятор переводит программу, написанную для машины M1, в эквивалентную программу, написанную для машины M2. Целевая машина может быть реализована аппаратно или быть виртуальной машиной. Концептуально разницы нет. Важным моментом является то, что компилятор смотрит на кусок кода и переводит его на другой язык, не выполняя его.
То есть интерпретатор не создает машинный язык, а компилятор делает это для его ввода?
Если при создании вы ссылаетесь на вывод, то компилятор создает целевую программу, которая может быть на машинном языке, а интерпретатор - нет.