Я слышал об идее начальной загрузки языка, то есть написания компилятора / интерпретатора для языка как такового. Мне было интересно, как это можно сделать, и я немного огляделся и увидел, что кто-то сказал, что это можно сделать только
- написание исходного компилятора на другом языке.
- ручное кодирование исходного компилятора на ассемблере, что кажется частным случаем первого
Мне кажется, что ни один из них не является начальной загрузкой языка в том смысле, что оба требуют внешней поддержки. Есть ли способ написать компилятор на его собственном языке?
Ответы:
У вас должен быть какой-то существующий язык для написания вашего нового компилятора. Если бы вы писали новый, скажем, компилятор C ++, вы бы просто написали его на C ++ и сначала скомпилировали с помощью существующего компилятора. С другой стороны, если вы создавали компилятор для нового языка, назовем его Yazzleof, вам сначала нужно будет написать новый компилятор на другом языке. Как правило, это другой язык программирования, но это не обязательно. Это может быть сборка, а при необходимости и машинный код.
Если бы ты был собираетесь самонастройки компилятора для Yazzleof, вы вообще не написать компилятор для полного языка на начальном этапе. Вместо этого вы должны написать компилятор для Yazzle-lite, наименьшего возможного подмножества Yazzleof (ну, по крайней мере , довольно небольшого подмножества). Затем в Yazzle-lite вы должны написать компилятор для полного языка. (Очевидно, это может происходить итеративно, а не за один прыжок.) Поскольку Yazzle-lite является правильным подмножеством Yazzleof, теперь у вас есть компилятор, который может компилировать себя.
Есть действительно хорошая статья о начальной загрузке компилятора с минимально возможного уровня (который на современной машине в основном представляет собой шестнадцатеричный редактор) под названием « Загрузка простого компилятора из ничего» . Его можно найти по адресу https://web.archive.org/web/20061108010907/http://www.rano.org/bcompiler.html .
источник
Вы прочитали правильное объяснение. Это обсуждается в « Компиляторах: принципы, методы и инструменты» (Книга Дракона):
источник
Супер интересное обсуждение этого в Unix сотворец Кен Томпсон «s премии Тьюринга лекции.
Он начинает с:
и переходит к демонстрации того, как он написал версию компилятора Unix C, которая всегда позволяла ему входить в систему без пароля, потому что компилятор C распознавал программу входа в систему и добавлял специальный код.
источник
Я слышал о том, чтобы написать чрезвычайно ограниченный компилятор на другом языке, а затем использовать его для компиляции более сложной версии, написанной на новом языке. Эту вторую версию затем можно использовать для компиляции самой и следующей версии. Каждый раз, когда он компилируется, используется последняя версия.
Это определение начальной загрузки:
EDIT: статья в Википедии о начальной загрузке компилятора охватывает эту концепцию лучше, чем я.
источник
Посмотрите подкаст Software Engineering Radio, выпуск 61 (2007-07-06), в котором обсуждается внутреннее устройство компилятора GCC, а также процесс начальной загрузки GCC.
источник
Дональд Э. Кнут фактически построил WEB , написав в нем компилятор, а затем вручную скомпилировал его в ассемблерный или машинный код.
источник
Насколько я понимаю, первый интерпретатор Lisp был загружен вручную путем компиляции функций конструктора и считывателя токенов. Остальная часть интерпретатора была затем прочитана из источника.
Вы можете убедиться в этом сами, прочитав оригинальную статью Маккарти « Рекурсивные функции символьных выражений и их машинное вычисление, часть I» .
источник
Другой альтернативой является создание машины для байт-кода для вашего языка (или использование существующей машины, если ее функции не очень необычны) и запись компилятора в байт-код, либо в байт-коде, либо на желаемом языке с использованием другого промежуточного звена, такого как набор инструментов синтаксического анализатора, который выводит AST как XML, а затем компилирует XML в байт-код с помощью XSLT (или другого языка сопоставления с образцом и представления на основе дерева). Это не устраняет зависимости от другого языка, но может означать, что большая часть работы по начальной загрузке завершится в окончательной системе.
источник
Это компьютерная версия парадокса курицы и яйца. Я не могу придумать, как не писать исходный компилятор на ассемблере или другом языке. Если бы это было возможно, я бы сделал это в Лиспе.
На самом деле, я думаю, что Lisp почти подходит. Посмотрите его запись в Википедии . Согласно статье, функция eval в Лиспе может быть реализована на IBM 704 в машинном коде, а полный компилятор (написанный на самом Лиспе) появится в 1962 году в Массачусетском технологическом институте .
источник
Каждый пример начальной загрузки языка, о котором я могу думать ( C , PyPy ), был сделан после того, как появился рабочий компилятор. Вы должны с чего-то начать, а для повторной реализации языка нужно сначала написать компилятор на другом языке.
Как еще это могло бы работать? Я не думаю, что иначе вообще возможно.
источник
Некоторые загрузочные компиляторы или системы сохраняют как исходную, так и объектную форму в своем репозитории:
ocaml - это язык, который имеет как интерпретатор байт-кода (т.е. компилятор для байт-кода Ocaml), так и собственный компилятор (для x86-64 или ARM и т. д. ассемблер). Его репозиторий svn содержит как исходный код (файлы
*/*.{ml,mli}
), так иboot/ocamlc
форму байт-кода (файл ) компилятора. Поэтому при сборке он сначала использует свой байт-код (предыдущей версии компилятора) для компиляции самого себя. Позже только что скомпилированный байт-код может скомпилировать собственный компилятор. Итак, репозиторий Ocaml svn содержит как*.ml[i]
исходные файлы, так иboot/ocamlc
файл байт-кода.В ржавчину загрузки компилятора ( с использованием
wget
, так что вам нужно подключение к Интернету рабочий) предыдущую версию двоичного файла компилироваться.MELT - это Lisp-подобный язык для настройки и расширения GCC . Он переводится в код C ++ с помощью загрузочного переводчика. Сгенерированный C ++ код переводчика распространяется, поэтому репозиторий svn содержит как
*.melt
исходные файлы, так иmelt/generated/*.cc
«объектные» файлы переводчика.Система искусственного интеллекта CAIA, разработанная Дж. Питратом, полностью самогенерируется. Он доступен в виде набора из тысяч
[A-Z]*.c
сгенерированных файлов (также со сгенерированнымdx.h
файлом заголовка) с набором из тысяч_[0-9]*
файлов данных.Также загружаются несколько компиляторов схем. Схема48, Схема с курицей, ...
источник