Раскрутка компилятора: различия между версиями

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску
[непроверенная версия][непроверенная версия]
Содержимое удалено Содержимое добавлено
Список языков, имеющих самокомпилирующиеся компиляторы: https://go-review.googlesource.com/#/c/5652/ Компилятор Go написан на Go
м Добавлено уточнение про python как самокомпилирующийся язык
 
(не показаны 32 промежуточные версии 21 участника)
Строка 1: Строка 1:
{{много внутренних ссылок}}
'''Раскрутка компилятора''' ({{lang-en|bootstrapping}}) это такой способ создания [[компилятор]]а для некоего [[Язык программирования|языка программирования]], когда компилятор пишется именно на целевом языке. Раскрутка также используется для переноса компиляторов на новые [[Аппаратная платформа компьютера|платформы]]. Основные идеи раскрутки появились в середине [[1950-е|1950-х]] годов. Применение этой техники позволяет создать компилятор, который компилирует сам себя. Метод раскрутки применялся для создания компиляторов многих языков программирования, включая компиляторы [[BASIC]], [[Алгол]], [[Си (язык программирования)|Си]], [[Паскаль (язык программирования)|Паскаль]], [[ПЛ/1]], [[Factor (язык программирования)|Factor]], [[Haskell]], [[Modula-2]], [[Оберон (язык программирования)|Oberon]], [[OCaml]], [[Common Lisp]], [[Scheme]], [[Java]], [[Python]], [[Scala (язык программирования)|Scala]], [[Nemerle]] и многих других.
'''Раскрутка компилятора''' ({{lang-en|bootstrapping}} от {{lang-en2|boot}} и {{lang-en2|strap}}) — метод создания [[транслятор]]а для некоторого [[Язык программирования|языка программирования]], при котором транслятор пишется на том же языке программирования, для трансляции которого создаётся; создание транслятором [[Исполняемый файл|исполняемых файлов]] из [[Исходный код|исходного кода]] самого транслятора. Используется для переноса трансляторов на новые [[Архитектура компьютера|архитектуры]]. Появился в середине [[1950-е годы|1950-х годов]]. Позволяет создать транслятор, который генерирует сам себя. Применялся для создания трансляторов многих языков программирования, включая языки «[[Бейсик]]», «[[Алгол]]», «[[Си (язык программирования)|C]]», «[[Паскаль (язык программирования)|Паскаль]]», «[[ПЛ/1]]», [[Factor (язык программирования)|Factor]], [[Haskell]], «[[Модула-2]]», «[[Оберон (язык программирования)|Оберон]]», [[OCaml]], [[Common Lisp]], [[Scheme]], [[Java]], *[[Python]] (Есть разные реализации этого проекта: CPython - на "[[Си (язык программирования)|C]]" (основная реализация), Jython - на "[[Java]]", и PyPy - самокомпилирующийся), [[Scala (язык программирования)|Scala]], [[Nemerle]], [[Kotlin]] и другие.
== Что вперёд: курица или яйцо ==

Если Вам нужен компилятор для языка X (который написан на языке X), то как написать первый компилятор? Решение [[Проблема курицы и яйца|проблемы курицы и яйца]] возможно следующими методами:
== Проблема курицы и яйца ==
* Создать [[интерпретатор]] или компилятор для языка X на языке Y. [[Вирт, Никлаус|Никлаус Вирт]] написал первый компилятор [[Паскаль (язык программирования)|Паскаля]] на [[Фортран]]е.
{{См. также|Проблема курицы и яйца}}
* Этот интерпретатор или компилятор для полной версии языка X уже может быть написан на языке Y кем-то другим; такая раскрутка часто применяется для языка Scheme.
Пусть создан новый язык программирования L. Пусть на языке L составлен исходный код транслятора для языка L. Как получить транслятор, способный из этого кода создать исполняемый файл?
* Первая версия компилятора может быть написана на подмножестве языка X, для которого уже существует некий другой компилятор; таким способом были раскручены некоторые подмножества Java, Haskell и [[Free Pascal]].

* Для создания компилятора языка X можно провести [[Кросс-компилятор|кросс-компиляцию]] на другой платформе, на которой уже существует компилятор для X; таким способом обычно портируются компиляторы, написанные на Си. Такой же способ используется для Free Pascal после начальной раскрутки.
Методы решения [[Проблема курицы и яйца|проблемы]] перечислены ниже:
* Написание компилятора на языке X; затем компилирование вручную из исходного кода (вероятно всего, без оптимизации) и выполнение полученного кода для получения оптимизированного компилятора. [[Кнут, Дональд Эрвин|Дональд Кнут]] использовал этот метод для своей системы [[Грамотное программирование|грамотного программирования]] [http://en.wikipedia.org/wiki/WEB WEB].

* Автор языка L может вручную выполнить трансляцию исходного кода с языка L на [[машинный код|машинный язык]] или на язык [[Ассемблер|ассемблера]]. Затем можно выполнить полученный код для создания исполняемого файла [[Компилятор|компилятора]]. Так поступили [[Вирт, Никлаус|Никлаус Вирт]] с учениками при создании первого компилятора для языка «[[Паскаль (язык программирования)|Паскаль]]», а также [[Кнут, Дональд Эрвин|Дональд Кнут]] при создании своей системы [[Грамотное программирование|грамотного программирования]] [[WEB (система программирования)|WEB]].

* Автор языка L может составить исходный код транслятора на языке, для которого уже существует транслятор. Попытку такого рода (впрочем, неудачную) предпринимал Никлаус Вирт при создании первого [[компилятор|компилятора]] для языка «Паскаль» на языке «[[Фортран]]».

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

* Первая версия компилятора может быть написана на подмножестве языка L, для которого уже существует некий другой компилятор. Таким способом были получены компиляторы для подмножества языков [[Java]], [[Haskell]] и [[Free Pascal]].

* Создать транслятор для новой платформы можно путём [[Кросс-компилятор|кросс-компиляции]] — создания исполняемого файла транслятора для новой платформы на платформе, для которой транслятор уже существует. Таким способом обычно [[Портирование программного обеспечения|портируются]] компиляторы, написанные на языках [[Си (язык программирования)|C]] и [[Free Pascal]].


== Раскрутка компилятора с использованием компилятора существующего языка ==
== Раскрутка компилятора с использованием компилятора существующего языка ==
Создание компилятора языка L методом раскрутки подразумевает последовательность некоторых шагов.
Создание транслятора языка L методом раскрутки подразумевает выполнение некоторых шагов.
# На первом шаге из языка L выделяется подмножество L<sub>0</sub>, которое не требует больших усилий для реализации, но является достаточным для написания компилятора самого себя. Затем, используя какой-либо существующий для этой платформы язык (например, [[Си (язык программирования)|C]]) программируется компилятор L<sub>0</sub>—С.
# На первом шаге из языка L выделяется подмножество L<sub>0</sub>, которое не требует больших усилий для реализации, но является достаточным для написания транслятора самого себя. Затем, используя какой-либо существующий для этой платформы [[Язык программирования|язык]] (например, [[Си (язык программирования)|C]]), составляется исходный код транслятора для L<sub>0</sub>.
# Затем на языке L<sub>0</sub> пишется компилятор самого языка L<sub>0</sub>, то есть L<sub>0</sub>—L<sub>0</sub>, который можно скомпилировать с помощью компилятора, полученного на первом шаге. После этого у программиста имеется компилятор L<sub>0</sub>, способный обработать свой [[исходный код]].
# Затем на языке L<sub>0</sub> составляется транслятор для самого языка L<sub>0</sub>. Исполняемый файл транслятора создаётся с помощью транслятора, полученного на первом шаге. После этого у программиста имеется транслятор L<sub>0</sub>, способный обработать свой [[исходный код]].
# Далее начинается постепенное расширение L<sub>0</sub> до L: добавляется какая-либо ранее не реализованная возможность языка L, после чего предыдущей версией компилируется новая, а вновь добавленную возможность можно использовать в компиляторе для последующего расширения языка. Именно этот процесс и называют раскруткой.
# Далее начинается постепенное расширение L<sub>0</sub> до L: добавляется какая-либо ранее не реализованная возможность языка L, после чего предыдущей версией транслятора создаётся новая, а вновь добавленную возможность можно использовать в трансляторе для последующего расширения языка.
Именно этот процесс и называют '''раскруткой'''.

Этапы раскрутки можно сократить: после написания компилятора "L<sub>0</sub>" c помощью "С" можно сразу писать компилятор "L" с помощью "L<sub>0</sub>".
Число шагов можно уменьшить, если после составления транслятора L<sub>0</sub> на языке [[Си (язык программирования)|С]] сразу начинать составлять транслятор L на подмножестве L<sub>0</sub>.


== Преимущества ==
== Преимущества ==
Достоинства метода раскрутки<ref>{{книга
У создания компиляторов методом раскрутки есть следующие преимущества:
|автор = Patrick D. Terry
<ref>{{книга
|заглавие = Compilers and Compiler Generators: An Introduction With C++
|автор = Patrick D. Terry
|ссылка = http://scifac.ru.ac.za/compilers/
|заглавие = Compilers and Compiler Generators: An Introduction With C++
|издательство = International Thomson Computer Press
|ссылка = http://scifac.ru.ac.za/compilers/
|год = 1997
|издательство = International Thomson Computer Press
|год = 1997
|isbn = 1850322988
|archive-date = 2011-07-29
|isbn = 1850322988
|archive-url = https://web.archive.org/web/20110729041846/http://www.scifac.ru.ac.za/compilers/
}}</ref>
}}</ref>:
* это - нетривиальная проверка языка, для которого делается компилятор;
* проверка возможностей языка L;
* порою разработчику достаточно знать только этот язык;
* отсутствие необходимости изучения других языков (порою разработчику достаточно знать только язык L);
* дальнейшие улучшения компилятора можно делать на языке высокого уровня;
* возможность дальнейшего улучшения транслятора на языке высокого уровня L;
* улучшение [[Кодогенерация|сгенерированного компилятором кода]] улучшает не только код программ вообще, но и код самого компилятора;
* постоянное улучшение качества кода (улучшение кода транслятора приводит к улучшению качества кода всех программ, создаваемых транслятором, включая сам транслятор);
* это - всесторонняя проверка компилятора на непротиворечивость, поскольку он должен быть в состоянии воспроизвести свой собственный код.
* всесторонняя проверка транслятора на непротиворечивость (транслятор должен быть способен воспроизвести свой собственный код).


== Недостатки ==
== Недостатки ==
В случае создания новых языков программирования, использование уже существующих языков может быть вполне оправданным по следующим причинам <ref>[http://www.compiler.su/raskrutka-kompilyatora.php Раскрутка компилятора]</ref>:
При создании новых языков программирования использование уже существующих языков может быть вполне оправданным по следующим причинам<ref>{{Cite web |url=http://www.compiler.su/raskrutka-kompilyatora.php |title=Раскрутка компилятора |access-date=2013-03-20 |archive-date=2020-08-09 |archive-url=https://web.archive.org/web/20200809231316/http://compiler.su/raskrutka-kompilyatora.php |deadlink=no }}</ref>:
* компиляторы уже существующих языков, как правило, надёжны;
* компиляторы уже существующих языков, как правило, надёжны (отлажены, изучены, стабильны);
* для уже существующих языков имеются [[Отладка программы|отладчики]] и другие инструменты;
* для уже существующих языков имеются [[Отладка программы|отладчики]], [[Статический анализ кода|статические анализаторы]] и другие инструменты;
* невозможность использования [[Синтаксический анализ|генераторов синтаксических анализаторов]];
* невозможность использования генераторов [[Синтаксический анализатор|синтаксических анализаторов]];
* использование интерпретатора для самоинтерпретации нового языка отрицательно скажется на скорости: сперва исполняемый код интерпретатора подмножества нового языка транслирует исходный код интерпретатора полной версии языка, и только затем полученный код интерпретатора будет выполнять интерпретацию пользовательской программы.
* использование интерпретатора для самоинтерпретации нового языка может отрицательно сказаться на скорости: старый интерпретатор интерпретирует код нового интерпретатора, который интерпретирует код сценария пользователя (двойная интерпретация)<ref>В некоторых случаях при двойной интерпретации производительность исполняемого файла может увеличиться. См. [[PyPy]].</ref>.


== История ==
== История ==
[[Ассемблер]] можно считать первым транслятором, который относительно просто реализуется непосредственно в машинных кодах.
Первыми языковыми инструментами, которые откомпилировали сами себя методом раскрутки, были ассемблеры. Первый язык высокого уровня, для которого был использован метод раскрутки, был [[Neliac]] в 1958 г. Первыми широко используемыми языками, которые были раскручены тем же способом, были Burroughs B5000 [http://en.wikipedia.org/wiki/Burroughs_B5000] Алгол в 1961 г. и Lisp в 1962 г. Харт и Левин написали компилятор Lisp на Lisp в [[Массачусетский технологический институт|Массачусетском технологическом институте]] в 1962 г., проверяя его на уже существующем интерпретаторе Lisp. Они перешли на него, как только разработанный ими компилятор смог откомпилировать свой собственный исходный код.

Компиляторами, созданными в [[Союз Советских Социалистических Республик|СССР]] и использовавшими технику раскрутки, были [[РЕФАЛ]], [[Сигма (язык программирования)|Сигма]] и [[Эпсилон (язык программирования)|Эпсилон]].
{{iw|Neliac}} — диалект языка «[[Алгол|Алгол{{nbsp}}58]]» и одноимённый компилятор, разработанные в 1958 году; первый язык высокого уровня, для которого был использован метод раскрутки.

Первыми широко используемыми языками, которые были раскручены тем же способом, стали:
* {{iw|Burroughs B5000|||Burroughs large systems#B5000}} («[[Алгол|Алгол{{nbsp}}60]]») в 1961 году;
* «[[Лисп]]» в 1962 году.

В 1962 году Тим Харт ({{lang-en|Tim Hart}}) и Марк Левин ({{lang-en2|Mark Levin}}) в [[Массачусетский технологический институт|Массачусетском технологическом институте]] написали первый [[компилятор]] «[[Лисп]]а» на языке Lisp<ref>{{cite web| title=AI Memo 39-The new compiler| author=Tim Hart and Mike Levin| url=ftp://publications.ai.mit.edu/ai-publications/pdf/AIM-039.pdf| accessdate=2006-10-13}}{{Недоступная ссылка|date=Июнь 2019 |bot=InternetArchiveBot }}</ref> и проверили его на уже существующем [[интерпретатор]]е языка Lisp. Они перешли на него, как только разработанный ими компилятор смог откомпилировать свой собственный исходный код.

В [[Союз Советских Социалистических Республик|СССР]] метод раскрутки использовался для создания компиляторов [[РЕФАЛ]], «[[Сигма (язык программирования)|Сигма]]» и «[[Эпсилон (язык программирования)|Эпсилон]]».

== Список языков, имеющих самокомпилирующиеся компиляторы ==
== Список языков, имеющих самокомпилирующиеся компиляторы ==
{{список примеров}}
* [[BASIC]]
* [[Алгол]]
* «[[Бейсик]]»
* «[[Алгол]]»
* [[Си (язык программирования)|Си]]
* [[Си (язык программирования)|C]]
* [[C++]]
* [[C++]]
* [[C_Sharp|C#]]
* [[CoffeeScript]]
* [[Common Lisp]]
* [[Common Lisp]]
* [[Eiffel]]
* [[Eiffel]]
* [[F Sharp]]
* [[F Sharp|F#]]
* [[Factor (язык программирования)|Factor]]
* [[Factor (язык программирования)|Factor]]
* [[Haskell]]
* [[Haskell]]
Строка 54: Строка 81:
* [[Java]]
* [[Java]]
* [[Mercury (язык программирования)|Mercury]]
* [[Mercury (язык программирования)|Mercury]]
* [[Modula-2]]
* «[[Модула-2]]»
* [[Nemerle]]
* [[Nemerle]]
* [[Оберон (язык программирования)|Oberon]]
* [[Оберон (язык программирования)|Oberon]]
* [[OCaml]]
* [[OCaml]]
* [[Паскаль (язык программирования)|Паскаль]]
* «[[Паскаль (язык программирования)|Паскаль]]»
* [[Perl 6]]
* [[Perl 6]]
* [[ПЛ/1]]
* «[[ПЛ/1]]»
* [[Python]]
* [[Rust (язык программирования)|Rust]]
* [[Rust (язык программирования)|Rust]]
* [[Scheme]]
* [[Scheme]]
* [[Scala (язык программирования)|Scala]]
* [[Scala (язык программирования)|Scala]]
* [[Standard ML]]
*[https://urn-lang.com/ Urn]
{{Hider|
| title = История
| frame-style =
| title-style = text-align: left;
| content-style = text-align: left;
| hidden = true
| content =
Первый компилятор для языка [[ML]], как для самостоятельного языка (после его выделения из [[Logic for Computable Functions|LCF]] как [[Встраиваемый язык|встроенного]] и интерпретируемого) был написан {{iw|Карделли, Лука|Лукой Карделли|en|Luca Cardelli}} целиком на языке «[[Паскаль (язык программирования)|Паскаль]]» (включая [[Среда выполнения|среду выполнения]] ({{lang-en|runtime}})). Вскоре компилятор был переписан на диалекте «VAX{{nbsp}}ML» и получил название «Edinburgh{{nbsp}}ML». Этот компилятор служил платформой для исследования языка, постепенно приблизив ML к виду SML’90. Далее на нём был написан {{iw|Standard ML of New Jersey|SML/NJ|en|Standard ML of New Jersey}}, в то время как среда исполнения была переписана на языке [[Си (язык программирования)|Си]]. Затем был раскручен SML/NJ, и далее на его основе раскручивались все остальные реализации языка. В настоящее время существует более десятка компиляторов и несколько интерпретаторов, в том числе с нестандартными расширениями, все из которых написаны на SML и обычно способны компилировать друг друга. Единственным исключением является неактуальный для SML [[Динамическая компиляция|инкрементальный компилятор]] Poplog, написанный на [[Lisp]]-подобном языке POP-11, не поддерживающий современные стандарты языка SML и его библиотеки.
<ref>{{статья
|автор = MacQueen D.
|заглавие = Luca Cardelli and the Early Evolution of ML
|год =
|ссылка =
|ref = Cardelli and the Early Evolution of ML
}}</ref>}}
* [[TypeScript]]
* [[TypeScript]]
* [[XPL (язык программирования)|XPL]]
* [[XPL (язык программирования)|XPL]]
* [[РЕФАЛ]]
* [[РЕФАЛ]]
* [[Сигма (язык программирования)|Сигма]] <ref>[http://www.computer-museum.ru/books/n_mozaika/sigma_2.htm История Сигмы]</ref>
* «[[Сигма (язык программирования)|Сигма]]»<ref>[http://www.computer-museum.ru/books/n_mozaika/sigma_2.htm История языка Сигма] {{Wayback|url=http://www.computer-museum.ru/books/n_mozaika/sigma_2.htm |date=20130720031809 }}.</ref>
* [[Эпсилон (язык программирования)|Эпсилон]] <ref>[http://www.computer-museum.ru/books/n_mozaika/epsilon.htm История Эпсилон]</ref>
* «[[Эпсилон (язык программирования)|Эпсилон]]»<ref>[http://www.computer-museum.ru/books/n_mozaika/epsilon.htm История языка Эпсилон] {{Wayback|url=http://www.computer-museum.ru/books/n_mozaika/epsilon.htm |date=20130720030840 }}.</ref>

== Примечания ==
== Примечания ==
{{примечания}}
{{примечания}}
Строка 82: Строка 126:
|ответственный =
|ответственный =
|издание =
|издание =
|место = {{М.}}
|место = М.
|издательство = Вильямс
|издательство = Вильямс
|год = 2003
|год = 2003
|том =
|том =
|страницы = 681—684
|страницы = [https://archive.org/details/isbn_5845901898_819/page/n680 681]—684
|страниц = 768
|страниц = 768
|серия =
|серия =
Строка 93: Строка 137:
}}
}}
* {{книга
* {{книга
|автор = С. З. Свердлов
|автор = Свердлов{{nbsp}}С.{{nbsp}}З.
|часть = Самокомпилятор. Раскрутка
|часть = Самокомпилятор. Раскрутка
|заглавие = Языки программирования и методы трансляции
|заглавие = Языки программирования и методы трансляции
|оригинал =
|оригинал =
|ссылка =
|ссылка = https://archive.org/details/isbn_5469003787
|ответственный =
|ответственный =
|издание =
|издание =
|место = {{СПб.}}
|место = СПб.
|издательство = [[Питер (издательство)|Питер]]
|издательство = [[Питер (издательство)|Питер]]
|год = 2007
|год = 2007
|том =
|том =
|страницы = 427—431
|страницы = [https://archive.org/details/isbn_5469003787/page/n427 427]—431
|страниц = 638
|страниц = 638
|серия =
|серия =
Строка 110: Строка 154:
|тираж =
|тираж =
}}
}}
* ''[[Вирт, Никлаус|Вирт{{nbsp}}Н.]]'' Построение компиляторов, Москва, ДМК Пресс, 2010, ISBN 978-5-94074-585-3, ISBN 0-201-40353-6

== Ссылки ==
* http://www.compiler.su/raskrutka-kompilyatora.php
* http://www.compiler.su/raskrutka-kompilyatora.php



Текущая версия от 17:59, 17 апреля 2024

Раскрутка компилятора (англ. bootstrapping — от boot и strap) — метод создания транслятора для некоторого языка программирования, при котором транслятор пишется на том же языке программирования, для трансляции которого создаётся; создание транслятором исполняемых файлов из исходного кода самого транслятора. Используется для переноса трансляторов на новые архитектуры. Появился в середине 1950-х годов. Позволяет создать транслятор, который генерирует сам себя. Применялся для создания трансляторов многих языков программирования, включая языки «Бейсик», «Алгол», «C», «Паскаль», «ПЛ/1», Factor, Haskell, «Модула-2», «Оберон», OCaml, Common Lisp, Scheme, Java, *Python (Есть разные реализации этого проекта: CPython - на "C" (основная реализация), Jython - на "Java", и PyPy - самокомпилирующийся), Scala, Nemerle, Kotlin и другие.

Проблема курицы и яйца

[править | править код]

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

Методы решения проблемы перечислены ниже:

  • Автор языка L может составить исходный код транслятора на языке, для которого уже существует транслятор. Попытку такого рода (впрочем, неудачную) предпринимал Никлаус Вирт при создании первого компилятора для языка «Паскаль» на языке «Фортран».
  • То же, но автор языка L сам не составляет исходный код, а поручает эту операцию другому лицу. Такой способ часто применяется при создании трансляторов для языка Scheme.
  • Первая версия компилятора может быть написана на подмножестве языка L, для которого уже существует некий другой компилятор. Таким способом были получены компиляторы для подмножества языков Java, Haskell и Free Pascal.
  • Создать транслятор для новой платформы можно путём кросс-компиляции — создания исполняемого файла транслятора для новой платформы на платформе, для которой транслятор уже существует. Таким способом обычно портируются компиляторы, написанные на языках C и Free Pascal.

Раскрутка компилятора с использованием компилятора существующего языка

[править | править код]

Создание транслятора языка L методом раскрутки подразумевает выполнение некоторых шагов.

  1. На первом шаге из языка L выделяется подмножество L0, которое не требует больших усилий для реализации, но является достаточным для написания транслятора самого себя. Затем, используя какой-либо существующий для этой платформы язык (например, C), составляется исходный код транслятора для L0.
  2. Затем на языке L0 составляется транслятор для самого языка L0. Исполняемый файл транслятора создаётся с помощью транслятора, полученного на первом шаге. После этого у программиста имеется транслятор L0, способный обработать свой исходный код.
  3. Далее начинается постепенное расширение L0 до L: добавляется какая-либо ранее не реализованная возможность языка L, после чего предыдущей версией транслятора создаётся новая, а вновь добавленную возможность можно использовать в трансляторе для последующего расширения языка.

Именно этот процесс и называют раскруткой.

Число шагов можно уменьшить, если после составления транслятора L0 на языке С сразу начинать составлять транслятор L на подмножестве L0.

Преимущества

[править | править код]

Достоинства метода раскрутки[1]:

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

Недостатки

[править | править код]

При создании новых языков программирования использование уже существующих языков может быть вполне оправданным по следующим причинам[2]:

  • компиляторы уже существующих языков, как правило, надёжны (отлажены, изучены, стабильны);
  • для уже существующих языков имеются отладчики, статические анализаторы и другие инструменты;
  • невозможность использования генераторов синтаксических анализаторов;
  • использование интерпретатора для самоинтерпретации нового языка может отрицательно сказаться на скорости: старый интерпретатор интерпретирует код нового интерпретатора, который интерпретирует код сценария пользователя (двойная интерпретация)[3].

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

Neliac[англ.] — диалект языка «Алгол 58» и одноимённый компилятор, разработанные в 1958 году; первый язык высокого уровня, для которого был использован метод раскрутки.

Первыми широко используемыми языками, которые были раскручены тем же способом, стали:

В 1962 году Тим Харт (англ. Tim Hart) и Марк Левин (Mark Levin) в Массачусетском технологическом институте написали первый компилятор «Лиспа» на языке Lisp[4] и проверили его на уже существующем интерпретаторе языка Lisp. Они перешли на него, как только разработанный ими компилятор смог откомпилировать свой собственный исходный код.

В СССР метод раскрутки использовался для создания компиляторов РЕФАЛ, «Сигма» и «Эпсилон».

Список языков, имеющих самокомпилирующиеся компиляторы

[править | править код]

Примечания

[править | править код]
  1. Patrick D. Terry. Compilers and Compiler Generators: An Introduction With C++. — International Thomson Computer Press, 1997. — ISBN 1850322988. Архивировано 29 июля 2011 года.
  2. Раскрутка компилятора. Дата обращения: 20 марта 2013. Архивировано 9 августа 2020 года.
  3. В некоторых случаях при двойной интерпретации производительность исполняемого файла может увеличиться. См. PyPy.
  4. Tim Hart and Mike Levin. AI Memo 39-The new compiler. Дата обращения: 13 октября 2006. (недоступная ссылка)
  5. MacQueen D. Luca Cardelli and the Early Evolution of ML.
  6. История языка Сигма Архивная копия от 20 июля 2013 на Wayback Machine.
  7. История языка Эпсилон Архивная копия от 20 июля 2013 на Wayback Machine.

Литература

[править | править код]