@PhegasWroteAll

Как написать свой компилятор?

Объясните пожалуйста, как можно написать свой компилятор, я не много не понимаю стадию генерации кода. Нужно после построение ast генерировать это в машинный код нужной архитектуры? Хочется именно в этом разобраться, не считая байт-кода и виртуальных машин.
  • Вопрос задан
  • 566 просмотров
Решения вопроса 2
@nakehab607
Ой а лайков то книге дракона понаставили, я не могу)) Ее хоть кто нибудь читал?) Сейчас есть книги гораздо более ориентированные на практику. Книга Дракона же это скорее чисто академическое чтиво.

https://www.amazon.com/Crafting-Interpreters-Rober...
https://www.amazon.com/Writing-Interpreter-Go-Thor...
https://www.amazon.com/Writing-Compiler-Go-Thorste...
https://holub.com/compiler/

Ну а для развлечения исключительно можно почитать какие-нибудь статьи на тему, перечисленные в этом репозитории: https://github.com/codecrafters-io/build-your-own-x
Ответ написан
@rPman
В тупом виде - каждый оператор и инструкция языка в коде компилятора описаны набором машинных команд (точнее там что то в виде функции, генерирующей набор команд в соответствии со входными параметрами).

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

Есть еще оптимизация кода, скорее всего именно это определяет объем и сложность задачи, так как без нее это уже не так сложно.

Над компилятором существует еще ряд задач, которые может понадобиться решить, это работа с несколькими файлами исходников, препроцессор (это наверное стало нормой, некий промежуточный язык, обрабатывающий и преобразовывающий исходный код) или его аналоги, благодаря особенностям реализации и историческим наслоениям, процесс получения бинарного кода делят на этапы - создание объектного кода (когда код файла компилируется в промежуточный набор машинных команд но все еще не исполняемый) и линковка - сборка итогового исполняемого файла из объектного кода и библиотек статической линковки. Формально это достаточно простая операция, идет проверка завершенности, т.е. что каждая переменная или функция определены (компилятор может создавать объектный код использования библиотеки только на основе ее короткого описания, а вот линкер объединяет полученный код с библиотекой).

Иногда добавляют еще несколько стадий, например один язык может генерироваться не сразу в объектный код а в исходные коды другого языка, который уже существующим компилятором генерирует итоговый.

Или наоборот, вместо генерации машинного кода, используется коды выдуманной виртуальной машины, которая будет запускаться (транслироваться в реальном времени в машинный код) на разных архитектурах одинаково (например jvm и clr).

И в догонку, в мире уже столько наворотили языков что разрабатывать и поддерживать под каждый оптимальный компилятор становится сложно, что в мире придумали llvm - набор правил, стандартов, библиотек и утилит, включая байткод виртуальной машины и трансляторы на все архитектуры... к примеру opencl использует llvm как основу
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
sergey-gornostaev
@sergey-gornostaev Куратор тега Трансляторы
Седой и строгий
Содержимое этой книги в ответ не вместится.
60b76e70c748b529799442.jpeg
А ваш вопрос на столько общий, что короче не получится.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы