Upload
pynsk
View
68
Download
2
Embed Size (px)
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
Благодарю за внимание!