Я работал в течение нескольких лет в компании, которая обеспечила и CE и Linux для всех их аппаратных средств, таким образом, я довольно знаком с обеими сторонами этого уравнения.
это означает, что CE побеждает каждый раз? Нет. Я не предложил бы это вообще. Если бы Вы - магазин Linux, и Вы имеете большой опыт Linux и кодируете активы, Вы были бы глупы выбежать и пойти CE. Однако при входе в него с нуля, CE обычно имеет более низкий TCO. Разработчики с опытом Win32/C# являются более распространенными и следовательно менее дорогими. Вы также добираетесь намного больше "в поле" с CE, чем большинство других дистрибутивов, имея в виду более быстрое время выхода на рынок, если у Вас уже уже нет этих вещей сделанными внутренний.
Кажется, есть некоторая двусмысленность в вопросе между языком и библиотекой. Термины «внутренний DSL» и «внешний DSL» полезны, и я думаю, что они принадлежат Мартину Фаулеру .
«Внешний» DSL может быть автономным инструментом командной строки. Ему передается строка источника, он как-то разбирает ее и что-то с ней делает. Нет никаких реальных ограничений на то, как могут работать синтаксис и семантика. Его также можно сделать доступным в виде библиотеки, состоящей в основном из метода eval
; типичным примером может быть построение SQL-запроса в виде строки и вызов метода execute
в библиотеке СУБД; не очень приятная или удобная схема использования и ужасна, если распространяться по программе в больших масштабах.
"Внутренний" DSL - это библиотека, которая написана таким образом, чтобы воспользоваться особенностями основного (общего) языка, чтобы создать впечатление, что новый язык может быть встроен в существующий. В языках с богатым синтаксисом (C ++, C #) это означает использование перегрузки операторов способами, которые серьезно растягивают (или игнорируют) обычные значения символов операторов. На C ++ есть много примеров; несколько также на C # - инструментарий парсера Irony имитирует BNF довольно сдержанным способом, который хорошо работает.
Наконец, есть простая старая библиотека: классы, методы, свойства с хорошо подобранными именами .
Внешний DSL позволит вам полностью игнорировать проблемы межъязыковой интеграции, поскольку единственной библиотечной частью будет метод eval
. Но изобрести собственную цепочку инструментов - нетривиально. Люди всегда забывают об огромной важности отладки, интеллекта, подсветки синтаксиса и т. Д.
Внутренний DSL, вероятно, бессмысленное занятие, если вы хотите сделать это хорошо на C # и Java. Проблема в том, что если вы воспользуетесь особенностями одного основного языка, вы не обязательно сможете повторить трюк на другом языке. например, в Java нет перегрузки операторов.
Что оставляет простую старую библиотеку. Если вы хотите охватить C # и Java (по крайней мере), то вы несколько застряли в выборе языка реализации. Вы действительно хотите написать библиотеку дважды? Одна из возможностей - написать библиотеку на Java, а затем использовать IKVM для ее кросс-компиляции в сборки .NET. Это гарантирует вам идентичный интерфейс на обеих этих платформах.
С другой стороны, API будет выражаться в функциях с наименьшим общим знаменателем, то есть в функциях Java :). Никаких свойств, только методы getX / setX. Избегайте дженериков, потому что в этом отношении эти две системы совершенно разные. Кроме того, у этих двух методов различается даже стандартный способ именования ( camelCase
и PascalCase
), поэтому одна группа пользователей будет чувствовать запах крысы.
Если вы хотите заново описать свой язык, используя ANTLR , вы можете сгенерировать свой интерпретатор DSL на нескольких языках без необходимости вручную поддерживать их, включая все языки, которые вы упомянули плюс многое другое.
Antlr - это генератор парсера / лексера, имеющий большое количество целевых языков. Это позволяет вам описать свой язык один раз, без необходимости поддерживать несколько его копий.
См. Полный список целевых языков здесь .
Хотя я не хочу слишком сильно продвигать свой собственный проект, я хотел бы упомянуть PIL, платформенно-независимый язык , промежуточный язык, над которым я работал включить поддержку нескольких программных платформ (например, Java, Python, ...), особенно для внешних DSL. Общая идея состоит в том, что вы генерируете код в PIL (подмножество Java), который компилятор PIL может затем переводить на один из многих других языков, в настоящее время только на Java или Python, но в будущем будет добавлено больше.
I представили доклад об этом на конференции по разработке программного обеспечения и языков около 2 дней назад, вы можете найти ссылку на публикацию на веб-сайте PIL ( pil-lang.org ), если вам интересно.
Возможность перехода на язык реализации в случае, если вам нужно сделать что-то, что просто не поддерживается вашим DSL, или по причинам производительности (хотя я понимаю, что это не является приоритетом) .
Я изучаю DSL для реализации правил в движке правил на C #, некоторые правила действительно сложны и могут значительно измениться в будущем, поэтому возможность выхода на C # действительно полезна. Конечно, это нарушает кроссплатформенную совместимость, но на самом деле это просто способ обойти крайние случаи без изменения вашего DSL.
Лучше всего написать библиотеку на C (или на каком-нибудь языке вроде rpython, который будет генерировать C-код), а затем использовать SWIG или аналогичный для создания привязок для конкретного языка для C #, Java Python и т. Д.
Обратите внимание, что этот подход не поможет, если вы используете Javascript в браузере - вам придется писать библиотеку javascript отдельно. Если вы используете javascript через Rhino, вы сможете просто использовать привязки Java.
Можно интерпретировать JavaScript изнутри Java-программы напрямую, используя механизм сценариев, и, очевидно, также из C #. Python можно запускать на JVM и на движке .NET.
Я бы посоветовал вам изучить эти варианты, а затем написать свою библиотеку в общем подмножестве путей выполнения, доступных для выбранного вами языка. Я бы не стал писать его на языке, который требует перевода и преобразования сообщений, поскольку вы вводите шаг, который может быть очень и очень сложно отладить в случае проблем.
Я хотел бы расширить ответ Дариена. Я думаю, что ANTLR приносит то, что предоставляют некоторые другие инструменты лексера / парсера (по крайней мере, насколько мне известно). Если вы хотите создать DSL, который в конечном итоге генерирует код Java и C #, ANTLR действительно подойдет.
ANTLR предоставляет четыре основных компонента:
Ваш лексер, синтаксический анализатор и дерево грамматики могут оставаться независимыми от вашего окончательно сгенерированного языка. По факту, механизм StringTemplate поддерживает логические группы определений шаблонов. Он даже предусматривает наследование интерфейсов групп шаблонов. Это означает, что вы можете попросить сторонние лица использовать ваш анализатор ANTLR для создания, скажем, python, assembly, c или ruby, когда все, что вы изначально предоставили, было выходом java и C #. Выходной язык вашего DSL может быть легко расширен по мере изменения требований со временем.
Чтобы получить максимальную отдачу от ANTLR, вам необходимо прочитать следующее:
Окончательный справочник по ANTLR: Создание доменно-ориентированных языков