Table of Contents

Notable design patterns for domain-specific languages

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

Введение

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

Содержание

1. Создание на основе другого языка (Piggyback)

Обычно в предметно-ориентированном языке используются широко распространенные инструменты многих языков программирования: переменные, исключения, подпрограммы и пр. Тогда можно создавать новый язык поверх уже созданного. При этом новый язык компилируется/«переводится» в базовый. Примеры: Yacc и Lex.

2. Композиция из нескольких предметно-ориентированных языков (Pipeline)

Часто система может быть хороша описана с использованием нескольких предметно-ориентированных языков (например, математические уравнения, химические формулы, картинки, графы и т.д.). Тогда эти языки образуют последовательную цепь. Каждый язык обрабатывает только свои элементы, а оставшееся и/или результаты обработки своих елементов передает следующему по цепочке.

3. Создание на основе лексического анализа текста (Lexical processing)

Предметно-ориентированный язык программирования можно создать так, чтобы его можно было обрабатывать лексическим анализатором. Этот паттерн можно также совмещать с паттерном piggyback: после лексического анализа результат дать обрабатывать компилятору исходного языка. Благодаря использованию этого паттерна снижается стоимость создания языка. Большое количество подобных предметно-ориентированных языков было создано с помощью sed, awk, Perl, Python, m4 и др.

4. Расширение другого языка (Language extension)

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

5. Специализация другого языка (Language specialisation)

По аналогии с предыдущим пунктом, новый предметно-ориентированный язык может использовать только какую-то часть базового языка, не используя все его возможности. Например, могут быть удалены «небезопасные» элементы: динамическое выделение памяти, неосвобожденные указатели или потоки и т.д. Пре-процессинг нового языка проверяет, что соответвующих конструкций нету. Пример: Javalight, образованный от Java.

6. Преобразование в исходный код другого языка (Source-to-source transformation)

Исходный код предметно-ориентированного языка программирования может быть преобразован с помощью компилятора/интерпретатора/компановщика в исходный код какого-то уже существующего языка.

7. Облегчение работы со сложными структурами (Data structure representation)

Предметно-ориентированный язык, использующий этот паттерн, позволяет легко (user-friendly) инициализировать какие-нибудь сложные структуры (например, графы), если эффективность не является существенным параметром. Примеры: Prolog и Lisp, FIDO.

8. Конфигурация сложной системы (System front-end)

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

Как паттерны связаны между собой

Заключение

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