Недавно я прочитал всю книгу Дракона (просто для удовольствия, я на самом деле не планирую реализовать настоящий компилятор), и я остался с этим большим вопросом, болтающимся в моей голове.
Чем отличается реализация компилятора и интерпретатора?
Для меня компилятор состоит из:
- Лексер
- Parser (который создает дерево синтаксиса)
- Сгенерировать промежуточный код (например, 3-х адресный код)
- Сделайте все эти безумные вещи, чтобы оптимизировать, если хотите: -)
- Сгенерировать "сборку" или "собственный код" из 3-х адресного кода.
Теперь, очевидно, интерпретатор также имеет тот же лексер и парсер, что и компилятор.
Но что он делает после этого?
-
Он "читает" дерево синтаксиса и выполняет его непосредственно? (вроде как указатель инструкции, указывающий на текущий node в дереве, а выполнение - один большой обход дерева плюс управление памятью для стека вызовов) (и если да, то как это делается? надеясь, что выполнение лучше, чем огромный оператор switch, который проверяет, какой тип node он)
-
Создает ли он 3 кода адреса и интерпретирует это? (если да, как это делается? Опять же, я ищу что-то более элегантное, чем инструкция с переключателем длиной в милю)
- Он генерирует реальный собственный код, загружает его в память и запускает? (в какой момент я предполагаю, что это не интерпретатор больше, но больше похоже на компилятор JIT)
Также, в какой момент разрезается понятие "виртуальная машина"? Что вы используете на языке виртуальной машины? (чтобы быть понятным о моем уровне невежества, для меня виртуальная машина - VMWare, я понятия не имею, как концепция виртуальной машины применяется к языкам программирования/исполняющим программам).
Как вы можете видеть, мой вопрос довольно широк. В основном я ищу не только тот метод, который используется, но в основном для того, чтобы сначала понять большие понятия, а затем понять, как он работает в деталях. Я хочу уродливые, сырые детали. Очевидно, что это скорее поиски ссылок на вещи, которые нужно читать, а не ожидать, что вы ответите на все эти детали здесь.
Спасибо!
Daniel
EDIT: Спасибо за ваши ответы. Я понял, что мой титул вводит в заблуждение. Я понимаю "функциональную" разницу между компилятором и интерпретатором.
То, что я ищу, - это разница в том, как вы реализуете интерпретатор, а не компилятор.
Теперь я понимаю, как реализован компилятор, вопрос в том, как интерпретатор отличается от этого.
Например: VB6 явно является компилятором и интерпретатором. Теперь я понимаю часть компилятора. Тем не менее, я не могу понять, как при работе внутри IDE это может позволить мне остановить программу в любой произвольной точке, изменить код и возобновить выполнение с помощью нового кода. Это всего лишь один крошечный пример, это не тот ответ, который я ищу. То, что я пытаюсь понять, как я объясняю ниже, - это то, что происходит после того, как у меня есть дерево синтаксического анализа. Компилятор будет генерировать новый код из него на "целевом" языке. Что делает интерпретатор?
Благодарим за помощь!