Diomidis Spinellis. 2001. Notable design patterns for domain-specific languages. J. Syst. Softw. 56, 1 (February 2001), 91-99. DOI=10.1016/S0164-1212(00)00089-3 http://dx.doi.org/10.1016/S0164-1212(00)00089-3
Автор рассматривает паттерны проектирования для создания предметно-ориентированных языков программирования.
Обычно в предметно-ориентированном языке используются широко распространенные инструменты многих языков программирования: переменные, исключения, подпрограммы и пр. Тогда можно создавать новый язык поверх уже созданного. При этом новый язык компилируется/«переводится» в базовый. Примеры: Yacc и Lex.
Часто система может быть хороша описана с использованием нескольких предметно-ориентированных языков (например, математические уравнения, химические формулы, картинки, графы и т.д.). Тогда эти языки образуют последовательную цепь. Каждый язык обрабатывает только свои элементы, а оставшееся и/или результаты обработки своих елементов передает следующему по цепочке.
Предметно-ориентированный язык программирования можно создать так, чтобы его можно было обрабатывать лексическим анализатором. Этот паттерн можно также совмещать с паттерном piggyback: после лексического анализа результат дать обрабатывать компилятору исходного языка. Благодаря использованию этого паттерна снижается стоимость создания языка. Большое количество подобных предметно-ориентированных языков было создано с помощью sed, awk, Perl, Python, m4 и др.
Предметно-ориентированный язык может быть создан как расширение уже существующего языка. Он использует новые типы данных, семантические элементы или семантический сахар. Компилятор нового языка использует пре-процессинг для трансляции в старый язык. Пример: расширение ML до визуализации графов.
По аналогии с предыдущим пунктом, новый предметно-ориентированный язык может использовать только какую-то часть базового языка, не используя все его возможности. Например, могут быть удалены «небезопасные» элементы: динамическое выделение памяти, неосвобожденные указатели или потоки и т.д. Пре-процессинг нового языка проверяет, что соответвующих конструкций нету. Пример: Javalight, образованный от Java.
Исходный код предметно-ориентированного языка программирования может быть преобразован с помощью компилятора/интерпретатора/компановщика в исходный код какого-то уже существующего языка.
Предметно-ориентированный язык, использующий этот паттерн, позволяет легко (user-friendly) инициализировать какие-нибудь сложные структуры (например, графы), если эффективность не является существенным параметром. Примеры: Prolog и Lisp, FIDO.
Конфигурация системы часто приводит к появлению соответствующего предметно-ориентированного языка программирования, который облегчает работу по созданию новых функциональных возможностей, расширению и усложнению системы, для настройки которой не обойтись только изменениями параметров функций или только графическим интерфейсом.
В данной статье не были рассмотрены традиционные способы создания языков программирования, т.к. это уже хорошо описано во многих других источниках. При этом применение того или иного паттерна зависит от конкретной области предметно-ориентированного языка программирования. Автор надеется, что эта статья восполнит недостаток литературы по этому вопросу и облегчит создание новых предметно-ориентированных языков программирования.