MPS. Делаем простое расширение для языка JAVA

в 12:43, , рубрики: dsl, java, jetbrains, Блог компании JetBrains, метки: , ,
Введение

Аудитория Хабра весьма неоднородна, и сложно написать текст, одинаково годный для опытных DSL архитекторов и, в то же время, доступный для пытливых умов интересующихся студентов. Мы предполагаем целую серию статей про MPS, чтобы последовательно подводить нашего читателя от простых к более сложным вещам.

Сразу нужно отметить, что у пользователей MPS есть две абсолютно разные роли – “разработчик языка” и “разработчик на языке”. Для “разработчика на языке” MPS – это просто IDE, очень близкая по своему поведению к большинству IDE для привычных языков программирования. Более того, для “разработчика на языке” существует плагин, который позволяет программировать на языке, созданном в MPS, прямо из IntelliJ IDEA. Далее мы сосредоточимся на роли “разработчика языка”.

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

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

Основные понятия MPS

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

Это дерево состоит из нодов (node), у каждого из которых есть:

  • Дочерние ноды
  • Свойства (строковые, числовые, логические и т.п.)
  • Ссылки на другие ноды

Ноды в MPS объединяются в модели. Модель в MPS – это аналог пакета в языке Java.

Concept
Каждая нода AST имеет тип, который определяет состав этой ноды, ее поведение при редактировании, генерации и т.д. Этот тип в MPS называется концептом (concept). В грубом приближении, концепт и нод находятся в таком же отношении, как класс и объект в языке Java.

Декларация концепта в MPS описывает то, какие данные будут храниться в нодах этого концепта. Остальное поведение концепта (редактор, типовые ограничения, генератор) описываются в одноименных аспектах концепта – editor, typesystem, generator…

Язык — это просто набор концептов и их аспектов.

Generation
Аналог компиляции в MPS называется генерацией (generation). В результате генерации из модели получаются файлы на диске.

У генерации есть 2 стадии:
Model-to-Model transformation. На этой стадии MPS преобразует исходное AST по правилам, описанным в генераторном аспекте языка. В результате получается другое AST, на языке более низкого уровня.
Model-to-Text transformation. На этой стадии MPS берет модель, полученную на первом шаге, и преобразует каждый ее нод в текст, после чего записывает этот текст в файл на диске.

С основными понятиями закончили, давайте теперь познакомимся с MPS на примере следующей задачи.

Постановка задачи

На практике довольно часто приходится писать условный оператор в виде:

if (condition) { 
   statement; 
} 

В нашем примере мы собираемся реализовать в MPS специальную нотацию для такой конструкции, которая позволит записывать тот же код короче:

? condition : statement;

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

Ставим MPS себе на компьютер

Это самый простой этап. Нужно зайти на официальный сайт JetBrains и скачать дистрибутив MPS. Процесс установки доступен любому хаброюзеру (если не доступен, тот юзер явно не из хаброаудитории). В данной статье я буду приводить пример для MPS 3.0, установленном на MacOS X, однако на других операционных системах все выглядит аналогично.

Далее мы предлагаем нашему читателю посмотреть небольшой скринкаст того, как сделать простое расширение языка Java в MPS:

Подведение итогов

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

Ссылки по теме
habrahabr.ru/post/66178/
habrahabr.ru/post/122358/
habrahabr.ru/post/122650/
habrahabr.ru/post/68313/
habrahabr.ru/post/169711/
habrahabr.ru/post/74367/

confluence.jetbrains.com/display/MPSD2/Basic+notions
www.jetbrains.com/mps/documentation/index.html
confluence.jetbrains.com/display/MPS/Welcome+to+JetBrains+MPS+Space
confluence.jetbrains.com/display/MPSD2/MPS+User%27s+Guide

Автор: beenom

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js