Как создать язык в эти дни? - PullRequest
       45

Как создать язык в эти дни?

9 голосов
/ 11 октября 2009

Мне нужно приступить к написанию того языка программирования, который я хотел написать. Как вы, дети, делаете это в эти дни? Я был вне цикла более десяти лет; Вы делаете это иначе, чем мы делали еще до Интернета, до Windows? Вы знаете, когда «настоящие» кодеры кодировали на C, использовали командную строку и обсуждали, какая оболочка была лучше?

Просто, чтобы уточнить, я имею в виду, не как вы ДИЗАЙН язык (который я могу понять довольно легко), а как вы строите компилятор и стандартные библиотеки и так далее? Какие инструменты вы, дети, используете в эти дни?

Ответы [ 19 ]

7 голосов
/ 11 октября 2009

Еще одно соображение, которое является новым с эпохи перфокарт, - это наличие виртуальных машин, которые уже обильно снабжены «стандартными библиотеками». Ориентация на JVM или .NET CLR вместо старого «языкового сада» избавит вас от начальной загрузки. Если вы создаете скомпилированный язык, вы также можете найти байт-код Java или MSIL более простой целью компиляции, чем машинный код (конечно, если вы хотите развить компилятор с жесткой оптимизацией, вы увидите это как ошибка, а не функция).

С другой стороны, идиомы JVM или CLR могут не соответствовать вашим языкам. Таким образом, вы все равно можете в конечном итоге создать «стандартные библиотеки» просто для обеспечения идиоматических интерфейсов через платформу (Примером является то, что каждый язык и его собака, кажется, предоставляют свой собственный метод для записи в консоль, вместо того, чтобы предоставлять пользователям возможность вручную вызывать System.out.println или Console.WriteLine.) Тем не менее, это позволяет постепенно развивать идиоматический библиотеки, а это означает, что более непонятные библиотеки, для которых вы никогда не задумывались о создании идиоматических интерфейсов, по-прежнему доступны, даже если это ужасно.

Если вы рассматриваете интерпретируемый язык, .NET также поддерживает эффективный перевод с помощью динамического языка исполнения (DLR). (Я не знаю, есть ли эквивалент для JVM.) Это должно помочь вам сосредоточиться на дизайне языка, не беспокоясь об оптимизации интерпретатора.

6 голосов
/ 11 октября 2009

Я написал два компилятора сейчас на Haskell для небольших предметно-ориентированных языков и нашел, что это невероятно продуктивный опыт. Библиотека parsec упрощает игру с синтаксисом, а интерпретаторы очень просто записывать поверх структуры данных Haskell. Есть описание написания интерпретатора Lisp на Haskell , которое мне показалось полезным.

Если вы заинтересованы в высокопроизводительном бэкенде, я рекомендую LLVM . Он имеет лаконичный и элегантный байт-код и лучший бэкэнд для генерации x86 / amd64. Существует дополнительный сборщик мусора и некоторые экспериментальные бэкэнды, которые предназначены для JVM и CLR .

Вы можете написать компилятор на любом языке, который создает байт-код LLVM. Если вы достаточно предприимчивы, чтобы изучать Haskell, но хотите LLVM, есть набор привязок Haskell-LLVM .

3 голосов
/ 11 октября 2009

Что значительно изменилось, но еще не упоминалось, так это поддержка и взаимодействие IDE:

В настоящее время мы в значительной степени ожидаем Intellisense, пошаговое выполнение и проверку состояния «прямо в окне редактора», новые типы, которые сообщают отладчику, как их обрабатывать, и довольно полезные диагностические сообщения. Старого исполняемого файла "compile .x -> .y" недостаточно для создания языка. Окружающая среда - это не то, на чем нужно концентрироваться, но она влияет на готовность к усыновлению.

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

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

2 голосов
/ 11 октября 2009

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

Стандартные библиотеки - включают эквивалент всего в стандартных библиотеках C99, кроме setjmp. Добавьте все, что вам нужно для вашего домена. Разработайте простой способ сделать это, например, SWIG или встроенный FFI, такой как Ruby [не помнит имя модуля] и Python ctypes.

Возможность создания как можно большей части языка в языке является вариантом, но проекты, которые начинают делать, либо сдаются ( rubinius перешел на использование C ++ для частей своей стандартной библиотеки), либо предназначены только для исследований. цели ( Мозилла Нарцисс )

2 голосов
/ 11 октября 2009

Говоря как кто-то, кто только что создал очень простую сборку, такую ​​как язык и интерпретатор, я бы начал с .NET Framework или аналогичного. Ничто не может сравниться с мощным синтаксисом C # + при поддержке всего сообщества .NET при попытке написать большинство вещей. Отсюда я разработал простой формат байт-кода и синтаксис ассемблера и приступил к написанию моего интерпретатора + ассемблер.

Как я уже сказал, это был очень простой язык.

2 голосов
/ 11 октября 2009

Вы не должны принимать глупые решения, такие как использование новейших инструментов. Вы должны загрузить язык, написав минимальный компилятор в Visual Basic для приложений или аналогичном языке, затем написать все инструменты компиляции на новом языке и затем самостоятельно скомпилировать его, используя только сам язык.

Кроме того, каково предлагаемое название языка?

Я думаю, что в последнее время не было языков с именами ВСЕХ ЗАГЛАВНЫХ БУКВ, таких как COBOL и FORTRAN, поэтому я надеюсь, что вы будете называть это как MIKELANG со всеми заглавными буквами.

2 голосов
/ 11 октября 2009

Я почти уверен, что вы делаете то, что всегда делали.

Напиши какой-нибудь код и покажи миру свои результаты.

По сравнению с древними временами, есть некоторые инструменты, которые облегчат вашу работу. Могу ли я предложить ANTLR для анализа вашей языковой грамматики?

1 голос
/ 11 октября 2009

Я на самом деле ребенок, хаха. Я никогда раньше не писал реальный компилятор и не проектировал язык, но я закончил «Книгу Красного Дракона», поэтому я полагаю, что у меня есть идея (надеюсь).

Это будет зависеть в первую очередь от грамматики. Если это LR или LALR, я думаю, что инструменты вроде Bison / Flex будут работать хорошо. Если это больше LL, я бы использовал Spirit , который является компонентом Boost. Это позволяет вам писать грамматику языка в C ++ в EBNF-подобном синтаксисе, так что не нужно путаться с генераторами кода; компилятор C ++ компилирует грамматику для вас. Если что-то из этого не получится, я напишу грамматику EBNF на бумаге, а затем приступлю к выполнению какого-то тяжелого рекурсивного разбора спуска, что, похоже, работает; если C ++ может быть достаточно хорошо проанализирован с использованием RDP (как это делает GCC), то, я полагаю, с достаточным количеством модульных тестов и терпением вы могли бы написать целые компиляторы с использованием RDP.

Как только у меня будет запущен парсер и какое-то промежуточное представление, это будет зависеть от того, как он работает. Если это какой-то байт-код или компилятор собственного кода, я буду использовать LLVM или libJIT для его обработки. LLVM больше подходит для общей компиляции, но мне больше нравится API libJIT и документация. В качестве альтернативы, если я действительно ленив, я сгенерирую код на C и позволю GCC выполнить фактическую компиляцию. Другой альтернативой является нацеливание на существующую виртуальную машину, такую ​​как Parrot, JVM или CLR. Parrot - это виртуальная машина, разработанная для Perl. Если это просто интерпретатор, я пройдусь по дереву синтаксиса.

Радикальной альтернативой является использование Пролога, который имеет синтаксические особенности, которые замечательно имитируют EBNF. Хотя у меня нет опыта работы с ним, и если я не ошибаюсь (что я почти наверняка буду), Prolog будет довольно медленным, если его использовать для синтаксического анализа тяжелых языков программирования с множеством синтаксических конструкций и причуд (читай: C ++ и Perl).

Все это я буду делать на C ++, хотя бы потому, что я более привык писать на нем, чем C. Я бы держался подальше от Java / Python или чего-либо подобного для реального производственного кода (написание компиляторов на C / C ++ помогает сделать его переносимым), но я мог видеть себя использующим их в качестве языка прототипирования, особенно Python, к которому я неравнодушен. Конечно, я никогда не делал ничего подобного раньше, поэтому я не из тех, кто скажет.

1 голос
/ 09 марта 2010

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

Ханспитер Мессенбок, Искусство Никлауса Вирта

FTP: //ftp.ssw.uni-linz.ac.at/pub/Papers/Moe00b.pdf

1 голос
/ 17 октября 2009

On lambda-the-ultimate есть ссылка на Create Your Own Language Programming от Marc-André Cournoyer, которая описывает, как использовать некоторые современные инструменты для создания маленьких языков .

...