Раскрутка компилятора: различия между версиями
[непроверенная версия] | [непроверенная версия] |
→Список языков, имеющих самокомпилирующиеся компиляторы: дополнение, оформление |
|||
Строка 47: | Строка 47: | ||
При создании новых языков программирования использование уже существующих языков может быть вполне оправданным по следующим причинам<ref>[http://www.compiler.su/raskrutka-kompilyatora.php Раскрутка компилятора]</ref>: |
При создании новых языков программирования использование уже существующих языков может быть вполне оправданным по следующим причинам<ref>[http://www.compiler.su/raskrutka-kompilyatora.php Раскрутка компилятора]</ref>: |
||
* компиляторы уже существующих языков, как правило, надёжны ( |
* компиляторы уже существующих языков, как правило, надёжны (отлажены, изучены, стабильны); |
||
* для уже существующих языков имеются [[Отладка программы|отладчики]], [[Статический анализ кода|статические анализаторы]] и другие инструменты; |
* для уже существующих языков имеются [[Отладка программы|отладчики]], [[Статический анализ кода|статические анализаторы]] и другие инструменты; |
||
* невозможность использования [[Синтаксический анализ|генераторов синтаксических анализаторов]]; |
* невозможность использования [[Синтаксический анализ|генераторов синтаксических анализаторов]]; |
Версия от 05:35, 13 июля 2015
Раскрутка компилятора (англ. bootstrapping — от boot и strap) — метод создания транслятора[1] для некоторого языка программирования, при котором транслятор пишется на том же языке программирования; создание транслятором исполняемых файлов из исходного кода самого транслятора. Используется для переноса трансляторов на новые платформы. Появился в середине 1950-х годов. Позволяет создать транслятор, который генерирует сам себя. Применялся для создания трансляторов многих языков программирования, включая языки BASIC, Алгол, Си, Паскаль, ПЛ/1, Factor, Haskell, Modula-2, Oberon, OCaml, Common Lisp, Scheme, Java, Python, Scala, Nemerle и другие.
Пусть создан новый язык программирования L. Пусть на языке L составлен исходный код транслятора для языка L. Как получить транслятор, способный из этого кода создать исполняемый файл?
Методы решения проблемы перечислены ниже.
- Автор языка L может выполнить ручную трансляцию исходного кода оптимизирующего компилятора с языка L на машинный язык или на язык ассемблера (вероятнее всего, без оптимизации). Затем автор языка может выполнить полученный код для создания оптимизированного исполняемого файла компилятора. Так поступил Дональд Кнут при создании своей системы грамотного программирования WEB (англ.).
- Автор языка L может составить исходный код транслятора на языке, для которого уже существует транслятор. Например, Никлаус Вирт написал первый компилятор для языка Паскаль на языке Фортран.
- То же, но автор языка L сам не составляет исходный код, а поручает эту операцию другому лицу. Такой способ часто применяется при создании трансляторов для языка Scheme.
- Первая версия компилятора может быть написана на подмножестве языка L, для которого уже существует некий другой компилятор. Таким способом были получены компиляторы для подмножества языков Java, Haskell и Free Pascal.
- Создать транслятор для новой платформы можно путём кросс-компиляции — создания исполняемого файла транслятора для новой платформы на платформе, для которой транслятор уже существует. Таким способом, обычно, портируются компиляторы, написанные на языках C и Free Pascal.
Раскрутка компилятора с использованием компилятора существующего языка
Создание транслятора языка L методом раскрутки подразумевает выполнение некоторых шагов.
- На первом шаге из языка L выделяется подмножество L0, которое не требует больших усилий для реализации, но является достаточным для написания транслятора самого себя. Затем, используя какой-либо существующий для этой платформы язык (например, C), составляется исходный код транслятора для L0.
- Затем на языке L0 составляется транслятор для самого языка L0. Исполняемый файл транслятора создаётся с помощью транслятора, полученного на первом шаге. После этого у программиста имеется транслятор L0, способный обработать свой исходный код.
- Далее начинается постепенное расширение L0 до L: добавляется какая-либо ранее не реализованная возможность языка L, после чего предыдущей версией транслятора создаётся новая, а вновь добавленную возможность можно использовать в трансляторе для последующего расширения языка.
Именно этот процесс и называют раскруткой.
Число шагов можно уменьшить, если после составления транслятора L0 на языке С сразу начинать составлять транслятор L на подмножестве L0.
Преимущества
Достоинства метода раскрутки[2]:
- проверка возможностей языка L;
- отсутствие необходимости изучения других языков (порою разработчику достаточно знать только язык L);
- возможность дальнейшего улучшения транслятора на языке высокого уровня L;
- постоянное улучшение качества кода (улучшение кода транслятора приводит к улучшению качества кода всех программ, создаваемых транслятором, включая сам транслятор);
- всесторонняя проверка транслятора на непротиворечивость (транслятор должен быть способен воспроизвести свой собственный код).
Недостатки
При создании новых языков программирования использование уже существующих языков может быть вполне оправданным по следующим причинам[3]:
- компиляторы уже существующих языков, как правило, надёжны (отлажены, изучены, стабильны);
- для уже существующих языков имеются отладчики, статические анализаторы и другие инструменты;
- невозможность использования генераторов синтаксических анализаторов;
- использование интерпретатора для самоинтерпретации нового языка может отрицательно сказаться на скорости: старый интерпретатор интерпретирует код нового интерпретатора, который интерпретирует код сценария пользователя (двойная интерпретация)[4].
История
Ассемблеры были первыми компиляторами, способными компилировать сами себя методом раскрутки.
Neliac (англ.) — диалект языка Algol 58 и одноимённый компилятор, разработанные в 1958 году; первый язык высокого уровня, для которого был использован метод раскрутки.
Первыми широко используемыми языками, которые были раскручены тем же способом, стали:
- Burroughs B5000 (Алгол 60) в 1961 году;
- Lisp в 1962 году.
В 1962 году Тим Харт (англ. Tim Hart) и Марк Левин (англ. Mark Levin) в Массачусетском технологическом институте написали первый компилятор Lisp на языке Lisp[5] и проверили его на уже существующем интерпретаторе языка Lisp. Они перешли на него, как только разработанный ими компилятор смог откомпилировать свой собственный исходный код.
В СССР метод раскрутки использовался для создания компиляторов РЕФАЛ, Сигма и Эпсилон.
Список языков, имеющих самокомпилирующиеся компиляторы
Список примеров в этой статье не основывается на авторитетных источниках, посвящённых непосредственно предмету статьи. |
- BASIC
- Алгол
- Си
- C++
- Common Lisp
- Eiffel
- F Sharp
- Factor
- Haskell
- Go
- Java
- Mercury
- Modula-2
- Nemerle
- Oberon
- OCaml
- Паскаль
- Perl 6
- ПЛ/1
- Python
- Rust
- Scheme
- Scala
- Standard ML.
Первый компилятор ML как самостоятельного языка (после его выделения из LCF?! как встроенного интерпретируемого) был написан целиком на Паскале (включая рантайм-систему) Лукой Карделли[англ.]. Вскоре компилятор был переписан на диалекте «VAX ML» и получил название «Edinburgh ML». Этот компилятор служил платформой для исследования языка, постепенно приблизив ML к виду SML’90. Далее на нём был написан SML/NJ[англ.], в то время как рантайм-система была переписана на Си. Затем был раскручен SML/NJ, и далее на его основе раскручивались все остальные реализации языка. В настоящее время существует более десятка компиляторов и несколько интерпретаторов, в том числе с нестандартными расширениями, 100 % из которых написаны на SML и обычно способны компилировать друг друга. Единственным исключением является неактуальный для SML инкрементальный компилятор Poplog, написанный на Lisp-подобном языке POP-11 и не поддерживающий современные стандарты языка SML и его библиотек. [6]
Примечания
- ↑ Транслятор — компилятор или интерпретатор.
- ↑ Patrick D. Terry. Compilers and Compiler Generators: An Introduction With C++. — International Thomson Computer Press, 1997. — ISBN 1850322988.
- ↑ Раскрутка компилятора
- ↑ В некоторых случаях при двойной интерпретации производительность исполняемого файла может увеличиться. См. PyPy.
- ↑ Tim Hart and Mike Levin. AI Memo 39-The new compiler . Дата обращения: 13 октября 2006.
- ↑ MacQueen D. Luca Cardelli and the Early Evolution of ML.
- ↑ История языка Сигма.
- ↑ История языка Эпсилон.
Литература
- Альфред Ахо, Рави Сети, Джеффри Ульман. Раскрутка // Компиляторы: принципы, технологии и инструменты = Compilers: Principles, Techniques, and Tools. — М.: Вильямс, 2003. — С. 681—684. — 768 с. — ISBN 5-8459-0189-8.
- С. З. Свердлов. Самокомпилятор. Раскрутка // Языки программирования и методы трансляции. — СПб.: Питер, 2007. — С. 427—431. — 638 с. — ISBN 5-469-00378-7.