Создание эффективных внешних DSL

Какие инструменты существуют для меня, чтобы создать реальный, честный внешний вид DSL. И нет, я не говорю о злоупотреблении Ruby, Boo, XML или другом существующем языке или синтаксисе, я имею в виду REAL external DSL - мой собственный язык для моих собственных целей.

Я знаю, что есть несколько языковых верстаков, и я слышал о таких вещах, как "Ирония" для .NET. И, конечно, там ANTLR, Lex/Yaac и т.д., Но я боюсь, что они слишком сложны для того, что я пытаюсь сделать.

Пожалуйста, расскажите о инструменте построения DSL, который вы, возможно, использовали или слышали, и о ваших впечатлениях о том, как это помогает и каковы его недостатки.

Ответ 1

Я написал DSL в Boo, Irony.NET и инструментарий под названием Grammatica. Вы говорите, что генератор-синтаксис слишком сложный, но вы, возможно, слишком поспешны в своем суждении, на самом деле они достаточно просты в использовании, когда вы преодолеваете небольшую кривую обучения и открываете огромный мир возможностей, который легко переопределяет усилие. Я обнаружил, что для обозначения грамматики для большинства генераторов парсеров я получаю несколько слов, которые похожи на изучение регулярных выражений - вам нужно немного наклониться, чтобы позволить им войти, но награды значительны.

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

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

Я согласен в долгосрочной перспективе о внутренних и внешних DSL. Я написал внутреннюю DSL в Boo и должен был модифицировать свой синтаксис DSL, чтобы он работал, и это всегда казалось взломом. Та же самая грамматика, использующая Irony.NET или ANTLR, была бы столь же легко выполнить с большей гибкостью.

У меня есть сообщение , в котором обсуждаются некоторые варианты. Сообщение сосредоточено вокруг написания DSL для оценки выражения времени исполнения, но все инструменты одинаковы.

Мой опыт работы с Irony.NET был положительным, и с ним было реализовано несколько эталонных языков, что является хорошим местом для начала. Если ваш язык прост, совершенно не сложно вставать и работать. Существует также библиотека в CodeProject под названием TinyParser - эта действительно интересна, потому что она генерирует синтаксический анализатор как чистый исходный код, что означает, что ваш конечный продукт полностью свободен от ссылки третьих сторон. Однако я не использовал его сам.

Ответ 2

Если вы занимаетесь написанием автономных DSL, тогда вы изучаете компиляторы - никоим образом не обходимо. Конструкция компилятора - это важное знание программирования, и это действительно не так сложно, как обычно думают. Steve Yegge Ryst Programmer Food подводит итог знанию того, как правильно создавать компиляторы.

Существует множество способов начать работу. Я рекомендую проверить 2 статьи, упомянутые в статье: Хотите написать компилятор? Просто прочитайте эти две статьи. Первый, Пусть построит компилятор, очень доступен. Он использует Turbo Pascal как язык реализации, но вы можете легко реализовать его на любом другом языке - исходный код очень ясен. Паскаль - простой язык.

Как только вы получите хорошее представление о том, как все работает, и о терминологии, я рекомендую вникать в нечто вроде ANTLR. ANTLR имеет приятную IDE, ANTLRWorks, которая поставляется с интерпретатором и отладчиком. Он также дает действительно хорошие визуализации ваших грамматик "на лету". Я нашел его неоценимым в обучении.

ANTLR имеет несколько хороших учебных пособий, хотя сначала они могут быть немного подавляющими. Этот хорош, хотя он против ANTLR 2.0, поэтому вы можете столкнуться с несовместимостью с более новой версией (в настоящее время последней версией является 3.1).

Наконец, существует еще один подход к DSL: подход Lisp. Учитывая Lisp отсутствие синтаксиса (ваш код в основном абстрактные деревья синтаксиса), вы можете сформировать из него бесконечные языки, если вы привыкнете к круглым скобкам:).

Если вы идете с этим подходом, вы хотите использовать вложенный Lisp. В Java у вас есть Clojure, диалект Lisp, который безупречно взаимодействует с JVM и его библиотеками. Я не использовал его лично, но он выглядит хорошо. Для схемы существует GNU Guile, который лицензирован под LGPL. Для Common Lisp, ECL, также под LGPL. Оба используют интерфейс C для взаимодействия, поэтому вы можете в значительной степени внедрить их на любой другой язык. ECL уникален среди Lisps в том, что каждая функция Lisp реализована как функция C, поэтому вы можете написать код Lisp на C, если хотите (например, внутри собственных методов расширений), вы можете создавать C-функции, которые работают на объектах Lisp, а затем вызовите их из Lisp). Я использую ECL для побочного проекта на некоторое время, и мне это нравится. Сопровождающий довольно активен и отзывчив.

Ответ 3

Вы действительно должны проверить Ragel. Это основа для внедрения государственных машин в ваш обычный исходный код. Ragel поддерживает C, С++, Objective-C, D, Java и Ruby.

Ragel отлично подходит для написания парсеров файлов и протоколов, а также для перехода на внешний DSL-материал. Главным образом потому, что он позволяет выполнять любой код на переходах состояний и т.д.

Несколько известных проектов, которые используют Ragel, Mongrel, отличный рубиновый веб-сервер. И Hpricot, основанный на ruby ​​html-парсер, вроде вдохновленный jQuery.

Еще одна замечательная особенность Ragel заключается в том, как она может генерировать графики graphviz, которые визуализируют ваши государственные машины. Ниже приведен пример из статьи Зед Шоу статья о графиках состояний рейге.

диаграмма состояний ragel http://www.zedshaw.com/tips/HelloMachine_small.png

Ответ 4

Xtext для этого.

С веб-сайта:

Xtext - это основа для разработки языков программирования и доменные языки.

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

Ответ 5

Я использую Иронию с хорошими результатами. Большая часть об иронии заключается в том, что вы можете легко включить ее в любую рабочую среду, в которой вы будете использовать DSL. Я создаю внешний DSL, который я заполняю в семантическую модель, написанную на С#, поэтому ирония отличная. Затем я использую семантическую модель для генерации кода с помощью StringTemplate.

Ответ 6

Если вы планируете внедрять внешние DSL, Spoofax (http://strategoxt.org/Spoofax) является хорошим инструментом Language Workbench для этого. Это текстовый инструмент Langauge Workbench, основанный на парсере, который использует несколько современных технологий, таких как SDF, Stratego. Помимо внедрения DSL, вы можете получить очень богатые услуги редактора, такие как завершение кода, просмотр контуров, intellisense и т.д. Он использовался для создания нескольких языков, например. http://mobl-lang.org/. Проверьте это, чтобы получить представление об оказанной поддержке.

Проект Spoofax поставляется с готовым примером DSL-реализации и генератором Java-кода. Это может послужить отправной точкой для начала работы с инструментами.

В следующем учебном пособии подробно описывается использование этого инструментария langauge: http://strategoxt.org/Spoofax/Tour.

Надеюсь, что это поможет!

Ответ 7

Для серьезных внешних DSL вы не можете избежать проблемы синтаксического анализа; ANTLR - это наименьшее из того, что вам нужно. То, что вы хотите проверить, это системы преобразования программ, которые можно использовать для сопоставления произвольного синтаксиса DSL на целевые языки, такие как Java.

См. http://en.wikipedia.org/wiki/Program_transformation