что такое jetbrains mps

JetBrains MPS — IDE для разработки проблемно-ориентированных языков программирования

Введение

MPS — это среда разработки языков программирования на платформе Intellij Idea. Она предоставляет возможность моделировать языки программирования, описывать структуры, сосредотачиваясь конкретно на дизайне и бизнес-логике, не отвлекаясь на парсеры, лексеры и различные сторонние фичи языка. Что нужно сразу обозначить: язык, который разрабатывается с помощью MPS, не компилируется в рабочую программу. Чаще всего он генерируется в модели других языков либо в текстовую форму.

Почему я решил написать этот пост? Я считаю, что это очень недооцененная возможность, а недооценена она потому что порог вхождения очень высок, плюс это один из самых непопулярных продуктов JetBrains.

Документация очень подробная, описывает все возможности, но если нет осознания «что я делаю и зачем мне это делать», то она вряд ли будет полезна. Также есть серия уроков от JetBrains на YouTube, но опять же, я более-менее начал понимать, что происходит, только после двух просмотров всей серии и досканального изучения предлагаемых sample проектов.

Я планирую написать серию постов об этой замечательной среде, чтобы по окончанию прочтения у энтузиастов оставалось как можно меньше вопросов «как сделать эту штуку», и как можно больше понимания структуры, чтобы можно было эффективно пользоваться документацией. Познавать MPS мы будем во время создания языка для описания закономерностей погоды. Почему, собственно говоря, и нет?

Концепция

MPS (дальше — среда / MPS) предоставляет возможность создавать модули двух типов — Language и Solution. Первый является описанием языка и его аспектов, второй используется для разработки каких-либо проектов, тестирования языка / языков, расширений языков.

Я начну с Language.

Самое важное, что нужно понять с начала, — это процесс разработки языка и что с ним происходит потом.

Итак, 1 статья — 1 кусок конечного проекта.

Создаем проект в MPS

что такое jetbrains mps. Смотреть фото что такое jetbrains mps. Смотреть картинку что такое jetbrains mps. Картинка про что такое jetbrains mps. Фото что такое jetbrains mps

На данном этапе мы выбираем название проекта и название языка, также можно создать Sandbox solution — модуль, в котором мы будем смотреть, как работает наш язык.

что такое jetbrains mps. Смотреть фото что такое jetbrains mps. Смотреть картинку что такое jetbrains mps. Картинка про что такое jetbrains mps. Фото что такое jetbrains mps

У нас есть пустой проект. Совсем пустой. Но в языке WeatherPrediction есть вложенные директивы — structure, editor… Это аспекты языка — в них мы описываем поведение языка в разных ситуациях. Например, structure содержит основные концепты языка, а editor — то, как они будут отображаться в редакторе кода. Это должно звучать очень абстрактно, особенно если Вы еще не знакомы с MPS. Понимаю. Так что сразу в бой.

Сначала нам нужно объявить root концепт языка. В переводе на русский — мы создаем некую структуру, которая будет обобщать все другие структуры. В Java это был бы

что такое jetbrains mps. Смотреть фото что такое jetbrains mps. Смотреть картинку что такое jetbrains mps. Картинка про что такое jetbrains mps. Фото что такое jetbrains mps

У концепта есть 3 типа данных, которые он может содержать:

что такое jetbrains mps. Смотреть фото что такое jetbrains mps. Смотреть картинку что такое jetbrains mps. Картинка про что такое jetbrains mps. Фото что такое jetbrains mps

Что здесь происходит: Мы определяем концепт, называем его PredictionList, говорим, что его можно реализовать как root концепт и наследуемся от INamedConcept. Если посмотреть на его definition (Ctrl + B)

что такое jetbrains mps. Смотреть фото что такое jetbrains mps. Смотреть картинку что такое jetbrains mps. Картинка про что такое jetbrains mps. Фото что такое jetbrains mps

то мы увидим, что это interface concept, у которого есть property name: string, что, собственно говоря, логично из названия

Обратите внимание, что синтаксис похож на язык программирования. Это так: этот код написан на языке jetbrains.mps.lang.structure, который описывает концепты языка.

Если мы сейчас соберем проект и захотим посмотреть, что получилось, то нам нужно будет создать модель в модуле WeatherPrediction.sandbox.

что такое jetbrains mps. Смотреть фото что такое jetbrains mps. Смотреть картинку что такое jetbrains mps. Картинка про что такое jetbrains mps. Фото что такое jetbrains mps

что такое jetbrains mps. Смотреть фото что такое jetbrains mps. Смотреть картинку что такое jetbrains mps. Картинка про что такое jetbrains mps. Фото что такое jetbrains mps

Заменим no name на Saint Petersburg

Бум! У нас есть дефолтная визуализация концепта. Чтобы посмотреть AST, нажмите на любое место в редакторе и нажмите хоткей Alt + X

что такое jetbrains mps. Смотреть фото что такое jetbrains mps. Смотреть картинку что такое jetbrains mps. Картинка про что такое jetbrains mps. Фото что такое jetbrains mps

что такое jetbrains mps. Смотреть фото что такое jetbrains mps. Смотреть картинку что такое jetbrains mps. Картинка про что такое jetbrains mps. Фото что такое jetbrains mps

Здесь мы можем описать то, как будет отображаться наш PredictionList в редакторе кода.
Пока не будем вдаваться в подробности, как тут это все сделано, просто пишем [- и у нас создается массив ячеек. Все просто: в каждой ячейке — какой то константный текст / property / reference / children. И да, отображение описывается другим языком — jetbrains.mps.lang.editor.
Мы хотим, чтобы наш список предсказаний погоды выглядел следующим образом:
Weather prediction rules for %name%.

что такое jetbrains mps. Смотреть фото что такое jetbrains mps. Смотреть картинку что такое jetbrains mps. Картинка про что такое jetbrains mps. Фото что такое jetbrains mps

В первой ячейке — константный текст, во второй — , обращение к property по ключу name.

Пересобираем наш язык (Ctrl + F9) и смотрим в Sandbox solution, где мы до этого создали пустой PredicitonList по имени Saint Petersburg.

что такое jetbrains mps. Смотреть фото что такое jetbrains mps. Смотреть картинку что такое jetbrains mps. Картинка про что такое jetbrains mps. Фото что такое jetbrains mps

Все работает, AST то же самое, что и до наших модификаций.

На этом я, наверное, остановлюсь пока что, чтобы получить фидбек. В следующем посте я планирую добавить еще парочку концептов, а так же генерацию кода на Java.

Спасибо за внимание! Пожалуйста, все пожелания, непонятки и вопросы и пишите в комменты. Если вопросы конкретные и простые, отвечу в комментариях, иначе добавлю в следующий пост.

Источник

Как система JetBrains MPS позволяет достичь более широкого использование DSL-ей (языков специфичных для предметной области)

DSL-и (domain specific languages или языки для специфичных областей) известны программистам давно. Несмотря на это, они редко используются в реальных системах. В этой статье будет рассмотрено, что такое DSL-и, и почему они не получили широкого распространения. Также будет описано, как система JetBrains MPS решает проблемы, препятствующие их широкому использованию.

Так что же такое DSL? DSL это язык, созданный для решения задач в определенной предметной области. DSL-ями являются большинство декларативных языков, которые решают задачки в узких предметных областях. Например, SQL, регулярные выражения, XPath, Prolog, формулы в Excel. К сожалению, на этом список широко используемых DSL-ей заканчивается. Основное достоинство таких языков в том, что благодаря близости их конструкций к предметной области, код на этих языках очень ясен и краток. Более того, чтобы редактировать код на таких языках, не обязательно быть программистом. Если человек разбирается в предметной области, то он легко может писать код на таких языках благодаря своим знаниям.

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

Давайте посмотрим на причины того, почему DSL-и не используются широко. Первая причина — авторы таких языков фокусируются на замкнутых языках только для одной конкретной проблемы, вместо того, чтобы расширять существующие языки программирования общего назначения, такие как Java, PHP, JavaScript. На это существует причина: возможность появления неоднозначностей при совмещении таких расширений друг с другом. Другая причина — сложность создания языковой инфраструктуры, необходимой для реализации языка, и комфортной работы с ним.

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

К сожалению, все популярные языки программирования общего назначения основаны на текстовых грамматиках. У этих грамматик есть одно неприятное свойство: они могут быть неоднозначными, те возможно несколько интерпретаций одной и той же строки. Более того, если мы добавляем к Java новые конструкции при помощи расширения A, и добиваемся однозначности грамматики, а потом делаем то же самое с расширением B, может получиться так, что если мы возьмем Java и оба расширения, результирующая грамматика будет неоднозначной.

Чтобы добиться высокой производительности разработчика, необходимы интеллектуальные средства разработки. C появлением интеллектуальных редакторов, таких как в IntelliJ IDEA или в Eclipse, разработчикам бывает трудно переключится на редактирование текста в обычных редакторах. Текстовые редакторы не подсвечивают ошибки, не предоставляют контекстную помощь, не показывают меню с доступными вариантами, в них нет поддержки рефакторингов. Существуют фреймворки для создания интеллектуальных редакторов, например, IntelliJ IDEA Language API, XText, Oslo, но ни один из этих фреймворков не поддерживает расширяемые языки на должном уровне. Даже если нам не нужна расширяемость, создание поддержки языка с использованием этих средств требует хороших знаний в области языков программирования и занимает очень много времени. Как видно, инструментальная поддержка очень важна, но реализовать ее непросто.

Давайте подведем итог: люди занимаются не тем типом DSL-ей; для достижения увеличения производительности необходимо расширять существующие языки программирования общего назначения. Создавать же такие расширения сложно из-за того, что широко распространенные технологии не поддерживают совместимость расширений друг с другом.
Как JetBrains MPS решает указанные проблемы

Давайте теперь посмотрим на то, как MPS решает указанные проблемы. Для того, чтобы поддержать совместимость расширений друг с другом, MPS не работает с программами как с текстом. Вместо этого, MPS хранит их как синтаксическое дерево, и редактирование происходит напрямую, без промежуточного использования текста. Такой подход позволяет существенно упростить создание IDE, поскольку постоянное наличие синтаксического дерева позволяет легко реализовать подсветку ошибок, автоматическое дополнение, контекстные подсказки итп.

MPS решает проблему неоднозначности радикальным способом: если у нас нет текстовой грамматики, то у нас нет и неоднозначности. Такой подход, однако, не означает, что в MPS не используются грамматики. Вместо конкретного синтаксиса, в определении языка в MPS определяется абстрактный синтаксис (структура синтаксического дерева). Если вы знакомы с XML, то наверное знаете об XML Schema, которая напоминает способ описания синтаксиса, используемый в MPS.

что такое jetbrains mps. Смотреть фото что такое jetbrains mps. Смотреть картинку что такое jetbrains mps. Картинка про что такое jetbrains mps. Фото что такое jetbrains mps

Поскольку мы избавились от текстового представления, мы не можем использовать обычный текстовый редактор. Для работы с кодом мы используем специальный проекционный редактор. Для каждого узла синтаксического дерева, он создает проекцию — часть экрана с которой может взаимодействовать пользователь. При разработке MPS были приложены огромные усилия для того, чтобы такой редактор вел себя настолько близко к тестовому редактору, насколько это возможно. Например, если вы введете 1 + 2 + 3 в MPS, вы получите тоже синтаксическое дерево, которое было бы получено при разборе этой строки в Java. Конечно, проекционный редактор отличается от текстового, и существуют вещи, которые возможны в одном и невозможны в другом, и наоборот. Несмотря на это, к этим различиям можно привыкнуть, не теряя в производительности. По нашему опыту, требуется около 2-х недель чтобы стать продуктивным в проекционном редакторе.

Создание поддержки интеллектуального редактирования при работе с синтаксическим деревом напрямую сильно упрощается. Более того, во многих местах, интеллектуальные возможности предоставляются MPS IDE без каких либо усилий со стороны автора языка. Такие возможности, как автоматическое дополнение, поиск использований, переименование, работают автоматически. При разработке IntelliJ IDEA, была реализована поддержка интеллектуального редактирования для многих языков. Реализация такой поддержки потребовала больших усилий: несколько человеко месяцев на язык. С MPS аналогичные возможности могут быть реализованы в считанные дни. Это возможно, поскольку для разработки языков используются специальные языки, которые конфигурируют существующую языковую инфраструктуру. MPS это не просто редактор. Вы можете создать полноценную IDE с его помощью.

Внутри JetBrains мы используем MPS для разработки коммерческих проектов. Наша новая система учета ошибок, с кодовым именем Харизма, создана полностью на MPS, и это только начало.
Заключение

Широкому использованию DSL-ей мешают 2 проблемы: невозможность их повторного использования в системах на основе текстовых грамматик, и сложность создания интеллектуальных средств работы с ними. MPS решает обе эти проблемы путем работы с синтаксическим деревом напрямую, без промежуточного текстового представления, и предоставляя инфраструктуру для создания интеллектуальных средств работы с такими языками.

MPS 1.0 был выпущен в июле. Большая часть кода доступна под лицензией Apache 2.0 (за исключение JetBreains IDE Framework, лицензия которой позволяет использовать MPS в продуктах на основе MPS, не покупая каких бы то ни было лицензий у JetBrains).

Источник

JetBrains MPS для интересующихся #1

Введение

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

Зачем нам нужен язык Weather?

С этой точки зрения, DSL — это как фреймворк, только с более удобным интерфейсом. Ясное дело, под один проект фреймворк делать никто не будет, за исключением совсем уж монструозных случаев. А сделать его под конкретную предметную область — почему бы и нет.

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

Синтаксис

Язык Weather, который мы хотим реализовать, должен выполнять следующую задачу: мы должны уметь лаконично выражать условия (погода сегодня, например) и следствия (погода завтра, послезавтра. ).
В языке Weather мы будем делать наши прогнозы отталкиваясь от 1 фактора: от температуры на сегодняшний день(массив объектов время + погодные условия).

У нас очень простые данные — время + температура в единицах измерения. Создадим абстрактный концепт WeatherTimedData — он нам нужен для хранения времени измерения и самой температуры.

что такое jetbrains mps. Смотреть фото что такое jetbrains mps. Смотреть картинку что такое jetbrains mps. Картинка про что такое jetbrains mps. Фото что такое jetbrains mps

Теперь нужно определить, что такое Temperature и Time.

что такое jetbrains mps. Смотреть фото что такое jetbrains mps. Смотреть картинку что такое jetbrains mps. Картинка про что такое jetbrains mps. Фото что такое jetbrains mps

что такое jetbrains mps. Смотреть фото что такое jetbrains mps. Смотреть картинку что такое jetbrains mps. Картинка про что такое jetbrains mps. Фото что такое jetbrains mps

Вот как я реализовал отображение в редакторе для Temperature:

что такое jetbrains mps. Смотреть фото что такое jetbrains mps. Смотреть картинку что такое jetbrains mps. Картинка про что такое jetbrains mps. Фото что такое jetbrains mps

Здесь у нас первая ячейка — double значение, величина температуры, а вторая — Read-Only model access. Здесь мы немного отдаляемся от практики и переходим к теории.

Теория

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

Можно было бы задать unit как переменную, а не писать абстрактный метод, но…
Есть аспект, называется Behavior. Все, что он может делать — добавлять новые методы к концепту. То есть добавить переменную мы не можем, поэтому будем использовать абстрактный метод.

что такое jetbrains mps. Смотреть фото что такое jetbrains mps. Смотреть картинку что такое jetbrains mps. Картинка про что такое jetbrains mps. Фото что такое jetbrains mps

И вот после этого мы можем у каждой реализации концепта Temperature вызывать этот метод. Но где же его вызывать? Как вообще кодить в этом MPS.

Снова практика

Мы остановились на том, что у нас есть непонятная ячейка в Editor аспекте — ReadOnly model access. Все очень просто — если нужно как-то логически обработать proeprty/children/reference перед тем, как его показывать, и на это не хватает встроенных приколов, то мы можем сами получить нужную строку из контекста редактора и реализации концепта. Если просто — нам дают текущий объект концепта, то есть реализованный, и мы можем из него получить все, что мы там понапихали. В данном случае мы хотим получить единицу измерения, поэтому мы нажимаем на ячейку R/O model access и пишем

что такое jetbrains mps. Смотреть фото что такое jetbrains mps. Смотреть картинку что такое jetbrains mps. Картинка про что такое jetbrains mps. Фото что такое jetbrains mps

Кстати, в любом месте кода вы можете тыкнуть на штучку, что Вас интересует и нажать Ctrl + Shift + T и получить информацию о типе этой штучки. Например, если мы нажмем на node в скрине выше и узнаем его тип, то мы получим

что такое jetbrains mps. Смотреть фото что такое jetbrains mps. Смотреть картинку что такое jetbrains mps. Картинка про что такое jetbrains mps. Фото что такое jetbrains mps

node = какая-то реализация концепта
concept = класс концепта
Так! Мы уже умеем составлять температуру по значению и единице измерения, но откуда мы возьмем, какая единица измерения нам нужна? Из дочерних реализаций, естественно.
Создаем пустой CelsiusTemperature концепт, расширяем Temperature и создаем для него behavior.

что такое jetbrains mps. Смотреть фото что такое jetbrains mps. Смотреть картинку что такое jetbrains mps. Картинка про что такое jetbrains mps. Фото что такое jetbrains mps

что такое jetbrains mps. Смотреть фото что такое jetbrains mps. Смотреть картинку что такое jetbrains mps. Картинка про что такое jetbrains mps. Фото что такое jetbrains mps

Остается только собрать все вместе в WeatherTimedData:

что такое jetbrains mps. Смотреть фото что такое jetbrains mps. Смотреть картинку что такое jetbrains mps. Картинка про что такое jetbrains mps. Фото что такое jetbrains mps

Собираем язык и смотрим на результат:

что такое jetbrains mps. Смотреть фото что такое jetbrains mps. Смотреть картинку что такое jetbrains mps. Картинка про что такое jetbrains mps. Фото что такое jetbrains mps

Вроде похоже на правду. Еще, конечно, нет самих предсказаний погоды, нет подсветки, к тому же часы у нас могут быть больше 24 и меньше нуля, минуты тоже не ограничены ничем, кроме размерности integer… В следующем посте ждите разъяснений по новому аспекту — constraints и еще чего-нибудь. А пока — пишите фидбек в комментариях, все как всегда, если вопрос простой — отвечаю там же, если он обширен и скорее как пожелание — то я постараюсь с каждым постом писать все качественнее. Спасибо за внимание!

//UPDATE\
Завел кривой репозиторий с проектом, где каждая ветка — новый туториал на Хабре. Это он.

Источник

MPS: изучаем метапрограммирование на примере ардуино

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

Немного теории и терминов

MPS — это аббревиатура для Meta Programming System, инструмента для метапрограммирования. Если уйти от деталей и попытаться дать простое определение, то метапрограммирование — это написание программ для написания программ. Можно тут вспомнить аналогию про метаданные, которые являются данными для описания других данных. А если ещё упростить, то метапрограммирование — это про создание DSL.

DSL, он же Domain-Specific Language, он же предметно-ориентированный язык — это язык, который использует термины определённого домена (области). По сути всё есть DSL, только домены отличаются. Например, для Java доменом является язык программирования и такие концепции, как «цикл», «метод», «переменная». Доменом для Gradle является сборка проектов, и там уже свои концепции: «зависимость», «задача», «артефакт». Поэтому под термин DSL можно притянуть почти всё что угодно. Тут могу порекомендовать статью от Federico Tomassetti под названием «The complete guide to (external) Domain Specific Languages».

Нам понадобится термин «модель» (model). DSL состоит из концепций, а пользователь создаёт их экземпляры. Вот эти экземпляры и образуют модели. Мне нравится, как это описано в материале от Microsoft «Understanding Models, Classes and Relationships».

На DSL можно посмотреть и с точки зрения инструмента, который позволяет научить общаться «говорящих» на разных языках. Например, человек на человеческом языке пишет: «У меня есть плата Arduino Uno, а на ней два LED и кнопка», а потом эти конструкции трансформируются в что-то другое, например в JSON-формат, который понятен какому-нибудь симулятору. Чем сложнее конструкции, тем применение DSL становится более оправданным.

Для наших целей подойдёт ресурс с эмулятором Arduino — wokwi. Этот ресурс позволит повторить действия из данной статьи, не устанавливая IDE для ардуино, и даже без него самого. Данный симулятор на вход принимает JSON-конфигурацию и использует её для симуляции. По схожей схеме могут работать и более сложные системы. Например, тестовый стенд для испытания реакции автомобиля под управлением компьютера.

Знакомимся с MPS

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

Открыв проект, мы увидим, что он состоит из разных «модулей». Подробнее про структуру проектов в MPS можно прочитать в разделе документации MPS project structure. MPS выделяет несколько типов модулей, но самые важные для нас — это Language (с иконкой L) и Solution (с иконкой S). Language-модули описывают DSL, а solution-модули используют Language-модули, чтобы в терминах того или иного языка создавать модели.

Каждая модель — своего рода обособленная область. По умолчанию они не видят ничего вокруг, однако можно импортировать объекты из других моделей и подключать разные языки. При подключении в модель языка мы можем создавать экземпляры концепций, которые добавляются данным языком. Например, раскроем в дереве проекта solution-модуль и перейдём курсором на модель sandbox (модели имеют иконку M). Из контекстного меню мы можем открыть Model Properties. Там на вкладке «Used Languages» мы увидим, какие языки подключены, а значит, термины из каких DSL мы можем использовать:

что такое jetbrains mps. Смотреть фото что такое jetbrains mps. Смотреть картинку что такое jetbrains mps. Картинка про что такое jetbrains mps. Фото что такое jetbrains mps

Скетчи и концепты

Закроем окно настроек, вернёмся к модели sandbox и нажмём ALT+INSERT, чтобы увидеть варианты того, что мы можем создать:

что такое jetbrains mps. Смотреть фото что такое jetbrains mps. Смотреть картинку что такое jetbrains mps. Картинка про что такое jetbrains mps. Фото что такое jetbrains mps

Например, воспользуемся WiringLang и создадим новый sketch. Прелесть JetBrains MPS в том, что MPS является своего рода фреймворком для написания DSL. Разработчику не нужно писать IDE, описывать работу выпадающих списков и прочее, а надо в правильном месте правильным образом описать тот или иной аспект языка. Благодаря этому мы можем воспользоваться CTRL+SPACE, чтобы открыть меню и увидеть, что нам доступно:

что такое jetbrains mps. Смотреть фото что такое jetbrains mps. Смотреть картинку что такое jetbrains mps. Картинка про что такое jetbrains mps. Фото что такое jetbrains mps

В случае с коллекциями элементов нажатием Enter в конце элемента мы создадим следующий. Таким образом при помощи WiringLang мы можем написать какой-нибудь пример с сайта wiring.org.co, например Blink:

что такое jetbrains mps. Смотреть фото что такое jetbrains mps. Смотреть картинку что такое jetbrains mps. Картинка про что такое jetbrains mps. Фото что такое jetbrains mps

Если мы встанем на любой объект, который мы создали, и откроем View→ Tool Windows → Inspector, то увидим информацию о том, какой концепт (описание концепции) отвечает за ту или иную фразу, которую мы наблюдаем:

что такое jetbrains mps. Смотреть фото что такое jetbrains mps. Смотреть картинку что такое jetbrains mps. Картинка про что такое jetbrains mps. Фото что такое jetbrains mps

В данном случае описание задержки выражено концептом Delay. В правой части у нас есть ссылка Open Concept Declaration, которая позволяет перейти непосредственно к описанию концепта.

Концепт — это основа, которая описывает сам факт существования какого-то термина и его структуру (из каких полей и ссылок состоит термин). Вокруг концептов описываются другие аспекты, такие как Constraints (ограничение доступных значений, ограничения возможности создавать экземпляры в том или ином месте в модели и прочее) или Editor (как показывать пользователю концепт):

что такое jetbrains mps. Смотреть фото что такое jetbrains mps. Смотреть картинку что такое jetbrains mps. Картинка про что такое jetbrains mps. Фото что такое jetbrains mps

При помощи Show Structure можно увидеть все описанные аспекты.

На примере аспекта Behavior важно сказать, что MPS — в первую очередь про Java. Концептам можно добавлять поведение и описывать это на Java, но с некоторыми дополнительными возможностями вроде своей обёртки над коллекциями (см. Collection Language) и других моментов:

что такое jetbrains mps. Смотреть фото что такое jetbrains mps. Смотреть картинку что такое jetbrains mps. Картинка про что такое jetbrains mps. Фото что такое jetbrains mps

Генератор: и всё превращается в текст

Одним из аспектов языка является генератор. Генераторы позволяют превращать модели либо в текст, либо в модель на другом языке. Предлагаю посмотреть на этот аспект JetBrains MPS несколько подробнее.

Генерация — это процесс преобразования одних моделей в другие. Например, если мы откроем наш ранее написанный скетч Blink и в контекстном меню выберем Preview Generated Text, то мы запустим генераторы и увидим результат. В нашем случае мы увидим текст, соответствующий тому, что указали в модели. Однако это полностью зависит от того, как написан генератор. Модель и конечный результат могут быть очень разными, что станет очевидно чуть позже.

Генерация устроена так, что в конечном итоге всё превращается в текст по тем или иным правилам. Это описано в аспекте TextGen. Например:

что такое jetbrains mps. Смотреть фото что такое jetbrains mps. Смотреть картинку что такое jetbrains mps. Картинка про что такое jetbrains mps. Фото что такое jetbrains mps

Как видно, генератор начнёт обрабатывать экземпляр концепта JSONDocument (см. выбранную вкладку), представляющий JSON-документ. В нём хранится JSON-объект, представленный концептом JsonObject, который является корневым элементом для JSON-структуры. Далее будет вызван TextGen-генератор для JsonObject. В свою очередь JsonObject будет вызывать TextGen для всего, что находится у него внутри. Таким образом, генераторы вызывают друг друга — получается своего рода матрёшка из результатов генераторов.

JSONSupport превращает модели в json-файлы, а WiringLang превращает модели в ino-файлы. Именно эти файлы использует симулятор ардуино wokwi.com. Но основной смысл в другом языке — MpsDemo. Этот язык превращает модели, написанные на нём, в модели JSON и Wiring. В этом случае используется специальный механизм шаблонов:

что такое jetbrains mps. Смотреть фото что такое jetbrains mps. Смотреть картинку что такое jetbrains mps. Картинка про что такое jetbrains mps. Фото что такое jetbrains mps

Чтобы понимать, как это устроено, советую пройти все обучающие материалы MPS из раздела Generator Demos, а также урок Shapes — an introductory MPS tutorial.

Приведу небольшой пример того, как выглядит шаблон для генератора:

что такое jetbrains mps. Смотреть фото что такое jetbrains mps. Смотреть картинку что такое jetbrains mps. Картинка про что такое jetbrains mps. Фото что такое jetbrains mps

Таким образом модель, написанная на MpsDemo, превращается в модели, написанные на JSON и Wiring DSL’ах. Те в свою очередь превратятся в текст.

Предлагаю на этом закончить краткий экскурс в то, как всё устроено изнутри, и рассмотреть один практический пример, ради которого вы читали весь этот текст =)

Симуляция с человеческим языком

Наша задача — описать следующую схему:

что такое jetbrains mps. Смотреть фото что такое jetbrains mps. Смотреть картинку что такое jetbrains mps. Картинка про что такое jetbrains mps. Фото что такое jetbrains mps

Симуляция будет строиться на основе платы Arduino Uno. У нас есть две лампочки красного цвета и одна кнопка. Мы хотим настроить эту схему так, чтобы при нажатии кнопки лампочки загорались.

Чтобы это заработало, нам нужно подключить к земле (GND на плате) катоды и один из контактов кнопки. Аноды подключим к одному пину платы, а ещё один контакт кнопки — к другому пину на плате.

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

Посмотрим на пример StopSig_test:

что такое jetbrains mps. Смотреть фото что такое jetbrains mps. Смотреть картинку что такое jetbrains mps. Картинка про что такое jetbrains mps. Фото что такое jetbrains mps

Как видно, описание сценария для симуляции написано понятным языком. Кроме того, в MPS можно реализовать перевод редакторов на разные языки (у нас есть английский и русский).

Дополнительные бонусы MPS

Кроме того, благодаря тому, что MPS — это фреймворк и IDE, мы можем воспользоваться различными средствами. Например, при помощи CTRL+SHIFT+I мы можем посмотреть информацию по тому объекту, где в данный момент установлен курсор. Например, тип создаваемых компонентов реализован при помощи специального концепта ComponentDefinition, экземпляры которого хранятся в аспекте, называемом Accessories Models. Это позволяет реализовать что-то вроде справочника. Встанем курсором на тип любого компонента (например, на LED) и нажмём CTRL+SHIFT+I:

что такое jetbrains mps. Смотреть фото что такое jetbrains mps. Смотреть картинку что такое jetbrains mps. Картинка про что такое jetbrains mps. Фото что такое jetbrains mps

Как Вы могли уже догадаться, первая часть нашего описания должна будет стать JSON’ом. Описание же поведения из нижней части сценария станет скетчем из WiringLang.

Вообще генератор при выполнении Rebuild для модели сохраняет результат генерации туда, куда указал генератор. Но проще всего смотреть через контекстное меню и опцию Preview Generated Text. Если мы откроем превью для нашего сценария, то увидим следующее:

что такое jetbrains mps. Смотреть фото что такое jetbrains mps. Смотреть картинку что такое jetbrains mps. Картинка про что такое jetbrains mps. Фото что такое jetbrains mps

Если мы создадим новую симуляцию на wokwi.com и вставим туда результаты генерации, то увидим работающую схему, где нажатие кнопки приводит к тому, что загораются LED.

Таким образом составитель этой схемы не писал ничего в JSON, не писал ничего на Wiring. Он просто написал человеческим текстом сценарий, а наш DSL превратил его в формат, который умеет читать симулятор. DSL выступил своего рода переводчиком между человеком и машиной, унифицировал способ описания сценария, а также предоставил удобный UI. Благодаря MPS нам доступна такая разработческая вещь, как интеграция с системой контроля версий. Кроме того, при необходимости мы можем написать собственный плагин для MPS, о чём подробно говорится в MPS User’s Guide: Plugin.

Стандартный компилятор vs. Wokwi

Вы спросите: а чем стандартный компилятор под ардуино не устраивает? Ведь описанную в статье историю с кнопкой и лампочкой можно написать в стандартном IDE. Так вот. Компилятор всем устраивает — wokwi просто позволяет, не имея ни ардуино, ни стандартного IDE, пощупать, как всё можно применить, и понять идею DSL. Это как онлайн-компиляторы под Java, которые помогают быстро посмотреть на код и что-нибудь быстро изучить, не устанавливая себе IDE.

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

Вывод

JetBrains MPS — действительно мощный инструмент. Написание DSL для генерации файлов с инструкциями/конфигурациями — лишь одно из возможных применений. MPS может быть встроен в обычный Java-проект при помощи плагина для системы сборки. MPS может не использовать генерацию, а просто позволять создавать модели и выполнять, зная про эту модель, какой-то Java-код. MPS — гибкий инструмент, он предоставляет широкие возможности, развивается и поддерживается, что тоже является огромным плюсом.

Из минусов — чем глубже погружаешься «в кишки» MPS, тем меньше документации. К MPS нужно привыкнуть, пройдя все стадии от отрицания до принятия. Надеюсь, вам как и мне, понравится этот путь.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *