Я создал несколько рукописных компиляторов для очень простых языков, но теперь я хочу попробовать свои силы в разработке динамического языка, похожего на упрощенный Python или Ruby. Однако мне было легко обдумать, как работают компиляторы. Примитивные компиляторы просто переводят. Но я не могу этого сделать, если язык динамичен. Мне нужно написать интерпретатор или виртуальную машину, которая отслеживает информацию во время выполнения и требует от меня гораздо больше работы.
Короче говоря, есть ли какие-то ресурсы, которые я должен проверить, учитывая, что знаю, как работают компиляторы, но хочу перейти на создание интерпретатора? Существует несколько виртуальных машин для динамических языков, но у меня нет проблем с прокруткой собственной. Это все только для моего личного опыта.
Я ищу информацию о том, как перейти от компилятора к интерпретатору. Если я уже сделал компилятор для языка X, но что теперь писать для интерпретатора, что нужно сделать, и есть ли какие-либо ресурсы, которые влияют на процесс?
Мне не нужны широкие или абстрактные ресурсы, рассказывающие о работе компиляторов или виртуальных машин. У меня много учебников на эту тему. Все ресурсы, которые я нашел в Интернете, предполагают, что у вас 0 опыта, и поэтому начинают с лексического или синтаксического анализа, или они чрезвычайно абстрактны. У меня есть работающий компилятор, но теперь я хочу превратить его в интерпретатор и добавить в язык динамические функции.
Я не мог найти ресурсы для этого процесса, он может быть слишком ограничен по объему, или ресурсы на «бэкэнде» переводчика, не будучи слишком теоретическими, поэтому я разместил здесь.
источник
Ответы:
Сначала узнайте о реализации переводчиков. Я рекомендую PLAI (Языки программирования: применение и интерпретация) . Он быстро достигает сути интерпретации, не останавливаясь на синтаксисе.
Для вашего языка вы сможете повторно использовать интерфейсную часть компилятора (в основном анализатор) и библиотеку времени выполнения (GC, структуры данных, примитивные операции и т. Д.).
Конечно, вы также можете реализовать динамический язык с помощью компилятора, который создает код, который манипулирует (некоторые из) теми же структурами данных, которые вы использовали бы в интерпретаторе. Например, в интерпретаторе вы можете реализовать глобальные переменные в виде хэш-таблицы с индексированной строкой. В компиляторе вы скомпилируете ссылки на глобальные переменные в код, который выполняет поиск, используя ту же таблицу. Напротив, вы можете скомпилировать лексические переменные в более эффективное представление («родные» аргументы и ссылки на структуру замыкания).
источник
Если вы хотите изучить основы реализации интерпретатора для динамического языка, я не могу представить себе лучшего места для начала, чем истоки самого первого динамического интерпретируемого языка программирования: Lisp.
В своей оригинальной статье 1960 года Джон Маккарти определил 5 примитивных функций, необходимых для Лиспа. Конечно, Маккарти только предназначил свою статью о Лиспе как академическое упражнение; это был аспирант, который участвовал
eval
в сборке и создал первого переводчика Lisp. Пол Грэм идентифицирует семь примитивов : цитата, атом, эквалайзер, автомобиль, CDR и конд.Дело в том, что вы можете реализовать Lisp на любом языке; После того, как вы внедрите
eval
, легко настроить REPL, и у вас будет интерактивный переводчик. Людям было скучно или достаточно любопытно реализовать Lisps на C, Java, Ruby, Python и многих других языках. И не всегда нарочно; важно помнить Десятое Правило Гринспуна :Я не говорю, что вашей конечной целью должна быть реализация Lisp; но гомойконичность имеет свои преимущества при обучении реализации динамического языка; зачем иметь дело с проблемами синтаксиса, когда вы можете учиться на языке, в котором идиоматический синтаксис идентичен AST языка, использующего лексер / парсер?
Во всяком случае ... просто предложение. Но есть веская причина, что большинство замечательных языков программирования, начиная с C, имеют хотя бы немного Lisp-природы.
источник
Я поместил это (~ 600 строк C #) в общественное достояние, которое поддерживает quote / list / apply / eval / test / etc и позволяет легко настроить Lisp-подобный синтаксис и / или семантические встроенные функции:
https://repl.it/CdjV/3
Например:
«НТН,
источник
Предполагая, что вы немного знакомы со Scheme (например, читали SICP ) или Lisp, я рекомендую книгу Queinnec Lisp In Small Pieces . Он объясняет несколько вариантов Lisp-подобных интерпретаторов и компиляторов (включая байт-код или C).
Кроме того, прочитайте « Прагматику языка программирования» Скотта , последнюю « Книгу драконов» , справочник по ГК , « Типы и языки программирования» Пирса .
Тогда частичная оценка (и проекции Футамуры) и стиль продолжения могут быть важны.
источник