Компилятор против интерпретатора (на основе конструкции и дизайна) - PullRequest
6 голосов
/ 20 ноября 2011

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

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

Мои основные сомнения:

1) Компилятор состоит из лексического анализатора,синтаксический анализатор, генератор промежуточного кода и генератор кода, но каковы части интерпретатора?

2) Кто обеспечивает поддержку во время выполнения интерпретируемых языков, я имею в виду, кто управляет кучей и стеками для рекурсивных функций?

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

a) мне пришлось бы управлять памятью {писать код для управления стеком и кучей} для него?

б) как этот компилятор будет отличаться от традиционного компилятора или, скажем, интерпретатора?

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

Я имею в виду сборник книг Альфреда В. Ахо


Основываясь на отзывах и дальнейших исследованиях, я думаю, что мне следует изменить свой вопрос

Компилятору не нужно выдавать только машинный код в качестве выходных данных

Но один вопрос все еще вызывает у меня сомнения. Допустим, я хочу создать компилятор (Python-> bytecode), и тогда байт-код будет интерпретироватьсявиртуальная машина .. (поправьте меня, если я ошибаюсь).
Затем мне придется написать лексический анализатор для Python, а затем парсер, который сгенерирует какое-то абстрактное синтаксическое дерево .. после этого мне придетсясгенерировать какой-нибудь промежуточный код (3-х адресный код, как упомянуто в книге драконов) или прямые инструкции байт-кода (которые, я полагаю, будут приведены в документации виртуальной машины)?

Придется ли мне писать код для обработки стекаа также для поддержки рекурсии и области действия?

1 Ответ

4 голосов
/ 20 ноября 2011

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

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

  2. Предполагая, что современные виртуальные машины довольно высокого уровня, это работа интерпретатора - есть специальные инструкции, среди прочего, для вызова функций и создания объектов, а сборка мусора выпекается в ВМ. Когда вы нацеливаетесь на машины более низкого уровня (такие как набор команд x86), многие такие детали должны быть вставлены в сгенерированный код, будь то напрямую (системные вызовы или что-то еще) или через вызов в реализацию стандартной библиотеки языка Си.

3

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

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

...