Как и зачем можно создать DSL на Python

Preview:

Citation preview

Как и зачем сделать DSL

Реализация DSL на Python

Доклад для #pynsk

Кто докладчик?

Михаил Воротынцев backend-разработчик.

Давно и много пишу на python и не только.Стараюсь поддерживать IT-движуху.

Domain-specific language

● Предметно-ориентированный язык

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

Domain-specific language

● Предметно-ориентированный язык

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

Почему это узкая область?

Например:

SQL, QML, YAML, JSON, ini-file, GraphQL

и многие другие...

Какая задача может появиться?

Предположим:

Нам нужно сделать язык описания рабочего процесса.

В нем должно быть:

● Описание задач и их последовательности.● Описание действий.● Описание сущностей участвующих в процессе.

И на все это свой синтаксис?

Надо подумать как он может выглядеть.

Во-первых,в рабочем процессе будет:

Действия

Задачи

Описание

Действия можно описать так:

<ключевое слово> <название> «<описание>»

Задачи тоже можно описать так:

Задачи будут выстраиваться в последовательность с помощью:

next <список следующих задач>

Задачи в последовательности образуют граф:

В простых случаях ациклический направленный граф.

Уже неплохо.

Но что-то забыли!

Сущности в рабочем процессе тоже нужны.

Сделаем описание похожим на что-то привычное: классы, структуры в знакомых нам языках.

Типы полей тоже выглядят привычно.

Сущности могут быть связаны:

Одни сущности могут быть полями в любых других.

Разнообразие сущностей.

Грядет много сущностей.

А как же в исполняемом коде определять какие у них есть возможности?

Нужно что-то вроде наследование.

Какие-то системные сущности будут наделять поведением пользовательские сущности.

Сделаем конструкцию import

Дополним описание действий сущностями.

Определены основные синтаксические конструкции нашего DSL.

Пора как-то разбирать этот код.

Как же это делать?

Намечается такой путь решения.

● Нужно создать синтаксический анализатор.

● Подходит исходящий синтаксический анализатор.

● Нужно получит решение реализующие метод рекурсивного спуска чтобы сконструировать наш язык через контекстно свободную грамматику.

Успешное решение близко.● Нужно создать какую-то свою грамматику разбирающую выражения.

● Эта РВ-грамматика должна получится похожа на регулярные выражения и на контекстно-свободные грамматики.

● Можем использовать расширенную форму Бэкуса-Наура или сделать что-то похожее.

Хороший план.

Оу..

Много сложных штук надо написать.Много времени уйдет.Еще и тестировать.

Конечно, взять готовое!

Есть готовое решение с документацией и лицензией MIT.

Примеры и обучающие материалы http://igordejanovic.net/textX/

Обязательно ознакомьтесь с проектом.

Теперь мы можем описать грамматику и код.

В переменной code строка кода с тем самым примером блока кода для конструкции import

Описание грамматики для import.

Строка с описанием грамматики.

Ой, точно!

Забыли комментарии. Добавим в грамматику:

Верно, нам нужны комментарии.

В коде пользоваться очень просто.

Мета-модель грамматики позволяет создать модель объектов кода по любому валидному тексту кода (в нашем случае он в переменной code)

Все нужные объекты будут созданы.

Грамматика

Код

Сделать остальные конструкциине на много сложнее.

Типы данных и сущности с их

свойствами можно легко описать.

Для этого кода подойдет такая грамматика:

Можно сделать грамматику для существующих языков.Например: вот так можно описать грамматику JSON

Новые возможности.

● Можно добавить в JSON грамматику возможность комментирования.

● Можно добавить формат даты и времени.

Но это уже не JSON, это уже just for fun.

Для чего еще можно использовать?

Можно разбирать формулу.

Пользователи нашего приложения что-то у себя считают по разным формулам и написали такую, например: (34 + a * -F) + (b ^ 10) * (10.1 + 1/(d - 1))

На этот раз code это некая формула (выражение)

Грамматика для разбора простых математических выражений:

И простая функция для разбора модели:

С конкретными значениями переменных вычисляем значение функции:

Получится такой вывод:

formula: (34.0 + 10 * -0.3) + (0.1 ** 10.0) * (10.1 + 1.0 / (2 - 1.0))result: 31.00000000111

В реальных условиях не используйте eval!

А что с задачей про DSL для рабочего процесса?

Она была решена!

Решение позволило создать двигатель рабочего процесса на основе своей нотации его описания.

● Celery - основа.● Умеют одновременно бежать много рабочих

процессов с возможностью дожидаться задач друг друга.

● Уже есть базовый набор сущностей.● Задумано для микросервисной архитектуры.

Для чего можно создавать DSL?

● Для инфраструктурных проектов.

● Для научных проектов.

● Еще один язык запросов-ответов.

● Для аналитиков, которые управляют бизнес-объектами в предметной области.

Время задать вопросы.

Если вопросы появятся, пишите в

@siberian_unax

Благодарю за внимание!