Изучение работы языков программирования - PullRequest
14 голосов
/ 04 октября 2009

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

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

Ответы [ 10 ]

12 голосов
/ 04 октября 2009

Код для исполнения в двух словах

Программа (код) подается в компилятор (или интерпретатор).

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

Эти токены объединяются в операторы: (int a = 6 + b * c;). В основном в виде синтаксического дерева:

                     =
                    / \
                   /   \ 
                  a     +
                       / \
                      /   \
                     6     *
                          / \
                         b   c

Внутри интерпретатора дерево выполняется напрямую.

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

Теперь у вас есть один или несколько «объектных файлов». Они содержат код ассемблера без точных переходов (потому что эти значения еще не известны, особенно если цели находятся в других объектных файлах). Объектные файлы связаны между собой компоновщиком, который заполняет пробелы для переходов (ссылки и ссылки). Вывод компоновщика представляет собой библиотеку (которая также может быть связана) или исполняемый файл.

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

4 голосов
/ 04 октября 2009

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

  • Некоторая форма предварительной обработки для файла, который обрабатывает макросы и тому подобное (например, из C).
  • A анализатор , который принимает исходные файлы, проверяет их соответствие синтаксическим правилам вашего языка и преобразует файл в структуру данных в памяти, которая более легко манипулировать другими частями программы. Это называется Абстрактный синтаксис Дерево или AST.
  • Некоторая форма анализа AST, которая проверяет, что реальный код, который вы написали, не нарушает никаких правил языка (например, рекурсия на языке, который его не поддерживает), а также многое другое.
  • Оптимизация , например, оптимизация хвостовых вызовов, оптимизация цикла и многие другие виды оптимизации.
  • Генерация кода , который представляет собой фактический процесс получения окончательного AST и любых других сгенерированных данных и преобразования их в двоичный файл некоторого вида, который может быть выполнен или интерпретирован.

Переводчик:

Интерпретатор - это программа, которая принимает в некоторой форме двоичные данные, которая представляет собой программу, не скомпилированную для кода, непосредственно исполняемого целевой машиной, и выполняет команды внутри. Примерами являются python, java и lua.

Собственный код:

Это код, который был скомпилирован в собственные инструкции, непосредственно исполняемые целевой машиной. Например; если вы работаете на архитектуре x86, то c ++ скомпилирует в исполняемый файл, понятный для процессора.

Виртуальная машина:

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

у этих ответов есть хорошие моменты, но эта информация и ссылки должны помочь вам начать. Любые другие вопросы, просто спросите!

(Большая часть этой статьи была написана с помощью Википедии, хотя часть была написана из памяти)

4 голосов
/ 04 октября 2009

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

Лично я узнал из книги Себесты . Это дает очень широкое введение в предмет, не вдаваясь в мелкие детали. Он также имеет хорошую главу по истории языков программирования (~ 20 языков ~ 3 статьи на язык). У этого есть хорошее объяснение о грамматике и теории языков вообще. Кроме того, он дает хорошее представление о схемах, прологах и парадигмах программирования (логика, функционал, императив ^, объектно-ориентированный).

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

3 голосов
/ 04 октября 2009

На этом сайте есть большая серия лекций по структуре и толкованию компьютерных программ, и это именно то, что вы хотите выучить. Прилагаемый учебник также полезен, хотя я лично не прочитал все это. Я думаю, что просмотр лекций довольно хорош, он дает вам около 60% пути.

2 голосов
/ 04 октября 2009

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

Похоже, что Аддисон-Уэсли перепечатал свою предшественницу, Книгу Зеленого Дракона, и выдал ее за что-то новое, поэтому будьте осторожны, чтобы получить подлинную статью.

2 голосов
/ 04 октября 2009

http://en.wikipedia.org/wiki/Dragon_Book_(computer_science) объяснит многие из этих понятий, вы должны прочитать его, это было для меня настоящим откровением.

2 голосов
/ 04 октября 2009

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

Чтобы дать вам быстрое вступление:

  • Компилятор: Программа, преобразующая написанный код в инструкции, понятные процессору.
  • Интерпретатор: Программа, которая читает написанный код и, на лету, переводит и дает соответствующие встроенные в процессор инструкции.
  • Управляемый код: Код, который запускается на виртуальной машине, например, обеспечить кросс-платформенную совместимость (Java).
  • Виртуальная машина: Программа, которая имитирует поведение, или, скорее, API, полноценной компьютерной среды. Помимо прочего, это дает некоторые преимущества безопасности и кроссплатформенную совместимость.
1 голос
/ 04 октября 2009

Эта серия лекций от Стэнфорда охватывает несколько языков программирования, вплоть до битов и болтов, включая Python (хотя я смотрел только пару из C).

1 голос
/ 04 октября 2009

Когда я узнал о программировании, где-то во второй половине прошлого века я понял, что все должно быть преобразовано в машинный код. Языки сценариев просто решают, какой код вызывать, основываясь на сценарии кода. Скомпилированный код сначала должен быть скомпилирован в p-код, который обозначает предварительно скомпилированный код, который необходимо связать с другим предварительно скомпилированным кодом для создания полного приложения. Тогда мне нравился Turbo Pascal, просто потому, что Turbo Pascal компилировался непосредственно в код machione, и он не использовал промежуточный p-код между ними. То есть до Turbo Pascal 4.0, который создавал * .tpu скомпилированные модули. Вместо этого большинство других компиляторов будут компилироваться в формат .obj.

Когда была создана Java, что-то относительно новое начало становиться популярным. По сути, компилятор Java просто компилирует код в некоторый двоичный файл сценария. Этот сценарий затем можно было бы интерпретировать, хотя вскоре этот механизм тоже изменился.

В настоящее время переводчики почти вымерли. Большинство скриптовых языков сначала компилируются в машинный код, машинный код затем сохраняется в некотором кеше, и, таким образом, он может выполняться очень быстро, без необходимости повторной интерпретации системой каких-либо повторяющихся инструкций. Это хорошо работает для текстовых и бинарных скриптов. PHP будет примером текстового скрипта. Java и .NET являются двоичными сценариями, так как вы обычно компилируете код в этот двоичный формат сценариев. (Они назовут это по-другому, но я думаю, что бинарные скрипты звучат лучше.)

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

Я также помню время, когда я мог написать приложение на C ++, где операторы SQL находились бы внутри самого кода. Это также было очень практично, но для этого требовался препроцессор, который сначала анализировал бы операторы SQL из кода, чтобы преобразовать его в другие операторы C ++ и заменяя операторы SQL этими более сложными командами C ++. Тогда все это будет скомпилировано в p-код. Затем вам нужно будет связать его с дополнительными библиотеками SQL, и, наконец, у вас будет исполняемый файл.

0 голосов
/ 04 октября 2009

Вы можете найти много лекций. Например, на Itunes U

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...