Самозагрузка все еще требует внешней поддержки

Я слышал об идее начальной загрузки языка, то есть написании компилятора / интерпретатора для самого языка. Мне было интересно, как это можно сделать, я немного огляделся и увидел, что кто-то сказал, что это может сделать только

  • написание исходного компилятора на другом языке.
  • ручное кодирование исходного компилятора в ассемблере, что кажется частным случаем первого

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

17.08.2008 06:46:11
Я не очень опытен с такими вещами, но я бы предположил, что первоначальный компилятор должен быть написан на другом языке. Я абсолютно уверен , что «самонастройки», со ссылкой на составителей, просто относится к написанию на компилятор для языка на языке это означало для компиляции, а не писать первый компилятор для языка в языке это означало для компиляции.
jdd 17.08.2008 06:57:05
Спасибо за информацию всем. Если объяснить идею сначала написать ограниченный компилятор, а затем построить его поверх этого, тогда идея начальной загрузки имеет больше смысла. В этом семестре я беру урок по компиляторам, на решение которого во многом повлиял пост Стива Йегге о том, насколько важен класс по компиляторам , и я только что купил копию книги «Дракон» по ссылке на Amazon, которая ранее была настолько сокращена на SO.
pbh101 17.08.2008 22:06:01
Смотрите также похожий вопрос: Реализация компилятора сама по себе
Urban Vagabond 2.11.2013 07:40:34
11 ОТВЕТОВ
РЕШЕНИЕ

Есть ли способ написать компилятор на его собственном языке?

У вас должен быть какой-то существующий язык для написания вашего нового компилятора. Если бы вы писали новый, скажем, компилятор C ++, вы просто написали бы его на C ++ и сначала скомпилировали его с существующим компилятором. С другой стороны, если вы создавали компилятор для нового языка, назовем его Yazzleof, вам сначала нужно написать новый компилятор на другом языке. Как правило, это будет другой язык программирования, но это не обязательно. Это может быть сборка или, при необходимости, машинный код.

Если вы были собираетесь самонастройки компилятора для Yazzleof, вы вообще не написать компилятор для полного языка на начальном этапе. Вместо этого вы должны написать компилятор для Yazzle-lite, наименьшего возможного подмножества Yazzleof (ну, по крайней мере , довольно маленького подмножества). Тогда в Yazzle-lite вы бы написали компилятор для полного языка. (Очевидно, что это может происходить итеративно, а не в одном прыжке.) Поскольку Yazzle-lite является подходящим подмножеством Yazzleof, теперь у вас есть компилятор, который может компилироваться сам.

Существует действительно хорошая статья о начальной загрузке компилятора с самого низкого возможного уровня (который на современной машине является в основном шестнадцатеричным редактором) под названием Bootstrapping простой компилятор из ничего . Его можно найти по адресу https://web.archive.org/web/20061108010907/http://www.rano.org/bcompiler.html .

107
9.04.2017 00:51:33

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

Это определение начальной загрузки:

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

РЕДАКТИРОВАТЬ: статья в Википедии о загрузке компилятора охватывает концепцию лучше, чем я.

5
17.08.2008 07:00:23

Объяснение, которое вы прочитали, верно. Это обсуждается в Компиляторах: Принципы, Методы и Инструменты (Книга Дракона):

  • Написать компилятор C1 для языка X на языке Y
  • Используйте компилятор C1, чтобы написать компилятор C2 для языка X на языке X
  • Теперь C2 является полностью самостоятельной хостинговой средой.
19
8.11.2012 23:44:23

Каждый пример начальной загрузки языка, который я могу придумать ( C , PyPy ), был сделан после того, как появился работающий компилятор. Вы должны начать с чего-то, и для повторной реализации самого языка требуется сначала написать компилятор на другом языке.

Как еще это будет работать? Я не думаю, что даже концептуально возможно сделать иначе.

2
8.11.2012 23:43:02
Первый компилятор Lisp, по крайней мере, был загружен с использованием существующего интерпретатора Lisp . Так что не семантически другой язык, а другая языковая реализация.
Ken 6.03.2010 21:52:54

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

На самом деле, я думаю, что Лисп почти готов. Проверьте его запись в Википедии . Согласно статье, функция Lisp eval может быть реализована на IBM 704 в машинном коде, а полный компилятор (написанный на самом Lisp) появился в 1962 году в MIT .

2
8.11.2012 23:35:35

Супер интересное обсуждение этого в Unix сотворец Кен Томпсон «s премии Тьюринга лекции.

Он начинается с:

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

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

Второй шаблон предназначен для компилятора Си. Заменяющий код - это самораспространяющаяся программа Stage I, которая вставляет оба троянских коня в компилятор. Это требует фазы обучения, как в примере Стадии II. Сначала мы скомпилируем модифицированный исходный код с помощью обычного компилятора C, чтобы получить бинарный двоичный файл. Мы устанавливаем этот двоичный файл как официальный C. Теперь мы можем удалить ошибки из исходного кода компилятора, и новый двоичный файл будет повторно вставлять ошибки всякий раз, когда он компилируется. Конечно, команда входа в систему останется ошибочной без следа в источнике нигде.

7
8.11.2012 23:37:54
Это не по теме .. Интересно, но запутанно, а не ответ на вопрос.
blueshift 25.03.2012 12:44:48

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

2
17.08.2008 13:21:16

Посмотрите подкаст Radio Engineering эпизод 61 (2007-07-06), в котором рассматриваются внутренние компоненты компилятора GCC, а также процесс начальной загрузки GCC.

4
8.11.2012 23:28:57

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

Вы можете проверить себя, прочитав оригинальную McCarthy бумагу, рекурсивные функции символических выражений и их вычисление с помощью машины, часть I .

3
8.11.2012 23:40:48
Что случилось с частями 2 и 3? ... Как я не заметил, что @Wing опубликовал то же самое за 3 года до меня? Я тупица По крайней мере, я связал бумаги (с помощью).
luser droog 30.03.2013 06:33:56

Дональд Э. Кнут фактически построил WEB , написав в нем компилятор, а затем скомпилировал его вручную для сборки или машинного кода.

4
8.11.2012 23:39:15

Некоторые загрузочные компиляторы или системы сохраняют как исходную форму, так и форму объекта в своем репозитории:

  • 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]*файлов данных.

  • Несколько компиляторов Scheme также загружаются. Scheme48, куриная схема, ...

0
1.05.2015 08:16:01