Мне было интересно, почему C ++ является хорошим выбором для написания компилятора. Конечно, C также хорош для этой цели, потому что многие компиляторы написаны либо на C, либо на C ++, но в этот раз меня больше интересует C ++. Есть веские причины? Я искал это в Интернете, но не могу найти веских причин.
14
Ответы:
С ++ имеет две стороны. Он имеет низкоуровневую сторону разработки, что делает его естественным языком для выполнения низкоуровневых вещей, таких как генерация кода. Он также имеет высокоуровневую сторону (чего нет у C), которая позволяет структурировать сложное приложение (например, компилятор) логическим, объектно-ориентированным способом, сохраняя при этом производительность. Поскольку он имеет как низко-, так и высокоуровневые аспекты, он является хорошим выбором для больших приложений, которые требуют низкоуровневых функций или производительности.
источник
Мой опыт не согласуется с вашей предпосылкой здесь. Фактически, для языков общего назначения высокого уровня, очень распространенной практикой является написание компилятора на том же языке, что и исходный (компилируемый язык). Например:
Исключением являются внешние интерфейсы компилятора, написанные для существующих сред компиляторов, таких как GCC, LLVM или Polyglot, которые затем пишутся на языке платформы, или компиляторы, которые полагаются на существующие генераторы синтаксических анализаторов, такие как Yacc. Поскольку GCC, LLVM и Yacc являются распространенными, устоявшимися инструментами, написанными на C и C ++, это дает стимул авторам компиляции использовать их, что может привести к тому, что C и C ++ получат большую долю в распределении языков реализации компилятора.
источник
javac
командная строка), который компилирует Java в Java Bytecode. Он написан на Java - я сам много раз его модифицировал, и вы можете просматривать его источники в Интернете . Другой - это компилятор, работающий точно в срок, встроенный в JVM Hotspot, который компилирует байт-код Java в машинный код. Как и большая часть JVM, она написана на C ++, но не является компилятором Java - фактически, она ничего не знает о языке Java.Компилировать что к чему? Компилятор преобразует исходный код с одного языка (исходный язык) на другой (язык назначения), что ничего не говорит о низком уровне языка назначения.
Язык, который вы выбираете для написания компилятора, зависит от контекста. Например, работая над проектом, который компилирует язык, производный от PHP, в нативный PHP-код, я использовал смесь PHP и C # для написания компилятора, потому что для меня это было наиболее целесообразно, учитывая мои навыки. Другой человек выбрал бы Python, или Java и PHP, или C ++ с небольшим количеством JavaScript, или что-то еще.
C или C ++ является популярным выбором из-за поддержки инструментов, связанных с компилятором (см. Ответ Telastyn), а также потому, что эти два языка позволяют вам работать по-настоящему. Но нет ничего плохого в выборе другого языка.
Обратите внимание, что для большей увлеченности вы можете выбрать исходный язык для написания самого компилятора. Это то, что произошло с компилятором CoffeeScript и многими другими компиляторами. Он также популярен среди IDE: одна из первых Visual Studio была построена с использованием той же Visual Studio.
источник
Я склонен ставить под сомнение основные предпосылки здесь. В то время как C и C ++ прекрасно работают для написания компиляторов, довольно много других языков, кажется, также отлично работают для этой задачи.
Хотя немного зависит от языка, который вы компилируете. Для небольших простых языков C и Pascal работают довольно хорошо. Если вы собираетесь скомпилировать что-то большое и сложное, ваш компилятор тоже станет большим и сложным - в этом случае дополнительные функции C ++ для организации и работы с более крупными программами, очевидно, пригодятся. Это на самом деле не очень специфично для компиляции, просто функции, полезные для больших программ в целом.
Я думаю, что стоит упомянуть еще один момент. Начинающие (кажется) думают о компиляторах, как в основном выполняющих манипуляции с текстом, поэтому они думают, что что-то вроде Perl будет огромной помощью при написании компиляторов. На самом деле, большинство интересных частей компиляции начинаются только после того, как вы создали AST. Хотя я уверен, что Perl может отлично справиться с этой задачей, его возможности манипулирования текстом на самом деле тоже не дают ему огромного преимущества (манипулирование текстом в основном в лексере, и генераторы лексеров для таких вещей, как C, все равно поддерживают RE).
источник
Компиляторы могут быть реализованы на любом современном языке. Однако одно из самых важных требований компилятора - это быть быстрым.
С ++ имеет явное преимущество здесь. Оптимизация в C ++ не обходится дешево. Однако из-за низкоуровневой природы этого языка можно вручную оптимизировать код C ++ больше, чем на любом другом языке (кроме Assembly, который не является переносимым).
источник
Я подозреваю, что основным мотивом для их использования является то, что вывод Lex / Yacc / Bison (главным образом) в C. Так как это было стандартом так долго, у него есть импульс.
Не то чтобы это были веские причины ...
источник
У меня есть опыт в этом вопросе. Я написал компиляторы на C и C ++. Основное различие между C и C ++ состоит в том, что C не имеет автоматического управления динамической памятью. Все управление памятью в C должно быть сделано явно. Написание компилятора очень важно для обработки строк и управления массивами. В C вы вынуждены думать о размере каждой строки и каждого объявленного вами массива, а также проверять индексы при доступе к этим объектам (если вы хотите, чтобы ваш код был безопасным и стабильным). Конечно, в C вы можете иметь динамическое управление памятью, но ничего не происходит автоматически. Вы должны явно выделять и освобождать память, используя malloc () и free (), сохраняя размер ваших динамических объектов в разделенных переменных, чтобы быть уверенным, что вы не обращаетесь к ним за пределами.
В C ++ вы можете иметь те же механизмы, но это действительно экономит время разработки, потому что все управление вашей памятью может быть заключено в конструкторы и деструкторы, которые вам не нужно вызывать явно. Таким образом, компилятор выделяет и освобождает ресурсы для вас. Размер ваших динамических объектов также может быть инкапсулирован, если вы создаете свои собственные классы, и индексы могут быть проверены на граничный доступ с помощью оператора перегрузки []. Эти абстракции помогают сделать ваш код чище, проще для понимания и отладки и, безусловно, ускоряют разработку.
Если вы создадите компилятор в C, это наверняка займет больше времени. C ++ заставит вас закончить ваш проект за меньшее время. C и C ++ имеют одинаковую производительность, но C ++ имеет много преимуществ, которых нет у C.
источник
Проект CompCert - это исследовательский компилятор C, который написан не на C или C ++, а на Ocaml и Coq.
Заметьте, что C ++ раньше переводили в C (в Cfront ). Теперь вы можете использовать интерфейс GCC для Gimple , затем выгрузить Gimple в некоторую базу данных, а затем написать Gimple для вашего ассемблерного переводчика. Но юридические причины ( исключение библиотеки времени выполнения GCC ) требуют, чтобы такой компилятор был открытым исходным кодом. Узнайте подробности у своего адвоката, я не юрист. Старые варианты GCC были написаны на C (+ несколько доменных языков) с внешним интерфейсом для некоторого варианта C ++. OpenWatcom может быть компилятором C ++, написанным на C (я оставляю вас проверить это).
Источник Compcert находится в свободном доступе для академических и исследовательских целей. Если вы хотите использовать его в промышленности (и на законных основаниях), вам необходимо получить лицензию от Absint.
Смотрите также это и это ответы на два связанных вопроса.
Если бы в 2020 году мне было поручено написать компилятор C (или C ++) с нуля (работающий в Linux, может быть, кросс-компилятор ), я, вероятно, не буду писать его на C ++. Я хотел бы написать это с помощью Ocaml , Go или Rust . И я мог бы основывать это на Frama-C, если это позволено. Если бы мне потребовалось кодировать на C или C ++, я бы сначала написал для него библиотеку сборщика мусора , возможно, некоторый постоянный уровень - очень полезный для оптимизации всей программы, - а затем я бы рассмотрел подход метапрограммирования (генерирующий большую часть кода C или C ++ из компилятор с моими специальными инструментами, возможно Bismon или RefPerSys если позволено).
Вы можете найти некоторые (более или менее с открытым исходным кодом) компиляторы C, написанные на Common Lisp или Python (например, ShivyC или nqcc ). Посмотрите также на ZetaC .
Обратите внимание, что последние версии GCC технически не кодируются на чистом C ++, они представляют собой дюжину доменных языков, участвующих в GCC (некоторые из них являются Turing-complete ). Смотрите также мой старый проект GCC MELT .
Я не удивлюсь, если в будущих версиях GCC в них будет встроен какой- либо интерпретатор Python или Guile (например, в качестве замены для менеджера проходов GCC).
Смотрите также в проект MILEPOST GCC .
источник