2. Что такое DSL и зачем он нужен?
Domain Specific Language — язык для
описания предметной области
Заточен под конкретную задачу
Предназначен для специалиста в
предметной области
Не требует навыков проектирования
программ
3. DSL подразделяются на
Внутренний DSL — является
подмножеством базового языка
программирования
Внешний DSL — не является
подмножеством базового языка
Текстовый
Графический
5. Что такое Xtext?
Высокоуровневый фреймворк для создания
DSL языков
Позволяет создавать IDE на основе Eclipse
platform
Использует для парсинга ANTLR 3
Хранит дерево разбора с помощью Eclipse
Modelling Framework
7. Интеграция с IDE
Подсветка синтаксиса
Автокомплит
Поддержка форматирования
Поддержка сообщения о ошибках
компиляции/предупреждениях
Поддержка построения графических и
структурных диаграмм кода
8. DSL с редактором — пример из
жизни
DSL как общая
часть портируемых
игр
DSL для общения
дизайнера и
програмиста
9. Пример языка: CasualIntellect
Поведение агента задаётся с помощью
конечного автомата
Состояние агента опрашивается на каждый
тик игрового цикла, если выполняется
условие производится переход в состояние,
если нет – проверка другого условия из
списка. Если никакое условие не
выполняется
10. Как работает язык casualintellect?
Язык задающий конечный автомат для
управления игровым агентом
11. Как же создать DSL за один день?
Создаём проект
Определяем
грамматику
Генерируем Xtext
артифакты
Имплементируем
метод в валидаторе
14. Проект UI
{Lang name}UiModule —
регистрация компонент
используемых с IDE
{lang name}ProposalProvider-
переопределение автокомплита
для всех правил грамматики
{lang_name}OutlineTreeProvider
— используется для управления
view outline
15. Определяем грамматику,
полезные детали
Список лексем Model:states+=State+;
Список с запятой, или его отсутствие
Transitions:
'transitions' ':' '{' list+=Transition? (Comma
list+=Transition)* '}';
Ключевое слово returns: Or returns Expression – Сгенерированный
интерфейс OR будет унаследован от Expression
16. Определяем грамматику,
полезные детали
Список лексем Model:states+=State+;
Список с запятой, или его отсутствие
Transitions:
'transitions' ':' '{' list+=Transition? (Comma
list+=Transition)* '}';
Ключевое слово returns: Or returns Expression – Сгенерированный
интерфейс OR будет унаследован от Expression
17. Определяем грамматику,
полезные детали
Фигурные скобки в теле выражения.
Entity: 'entity' {Entity} name = ID ('extends'
superType=[Entity])? '{'
attributes += Attribute*
'}' ; создаём сущность до полной инициализации.
18. Удаление левой рекурсии
Грамматика называется леворекурсивной,
если она содержит продукцию с вызовом
самой себя без продвижения по строке
Expression : Expression '+' Expression |
'(' Expression ')' |
INT;
ANTLR использует LL(*) алгоритм,
леворекурсивные грамматики он не парсит.
19. Удаление левой рекурсии
Грамматику можно менять с помощью
переписывания
Expression :
TerminalExpression ('+' TerminalExpression)?;
TerminalExpression :'(' Expression ')' |INT;
20. Удаление левой рекурсии
Но такое преобразование приведёт к созданию
лишних элементов AST. «(42)» будет
разобрано как
Operation {
left=Operation {
left=IntLiteral {
value=42
}
}
}
21. Удаление левой рекурсии
Чтобы избежать избыточности AST
произведём переписывание дерева
Expression :
TerminalExpression ({Operation.left=current}
op='+' right=Expression)?;
TerminalExpression returns Expression:
'(' Expression ')' |
{IntLiteral} value=INT;
22. Удаление левой рекурсии
Пытаемся разбирать выражение с помощью
правила TerminalExpression
Ищем опциональный + с последующим
другим выражением
• Если опциональная часть не найдена,
выражение совпадает с разобранным
элементом
• Иначе, создаём обьект «плюс» где левая
часть разобрана перед этим и правая часть
разбирается после +
23. Язык Xtend входной для Xtext
Выпущен Eclipse Fundation
http://www.eclipse.org/xtend/
Используется в Xtext начиная с версии 2.4
Транслируется в Java
Меньше шума – больше сахара
24. Язык Xtend входной для Xtext
Пример кода
class HelloWorld {
def static void main(String[] args){
println("Hello World")
}
}
25. Язык Xtend входной для Xtext
Сгенерированный код
import org.eclipse.xtext.xbase.lib.InputOutput;
@SuppressWarnings("all")
public class HelloWorld {
public static void main(final String[] args) {
InputOutput.<String>println("Hello World");
}
}
26. Язык Xtend, добавим сахару
Extension methods
Lambda Expressions
Switch with expressions
Patterns
Additional operators
27. Пишем код - кодогенерация
Интерфейс Igenerator
public void doGenerate(Resource input,
IFileSystemAccess fsa);
Проходит по узлам AST генерирует код
28. Пишем код - валидация
Используется для
постсинтаксического(семантического
анализа текста)
Класс наследуемый от
AbstractDeclarativeValidator
Для проверки используются методы
аннотированные @Check
Пример валидации:проверка
инициализации переменной до её
использования
29. Пишем код - форматирование
текста
Класс наследуется от
AbstractDeclarativeFormatter
Вставляем переход на новую строку,
увеличение/уменьшение отступа до и после
структуры данных
30. Пишем код - изменение outline
Класс наследуется от
DefaultEObjectLabelProvider
Содержится в ui проекте
Переопределяем метод text — изменяем
метку
Переопределяем метод image — изменяем
картинку
31. Тестирование
Xtext предоставляет полную поддержку TDD
Интегрирован с Junit 4(@Test, @Before,
TestSuite)
Аннотации для запуска тестов
XtextRunner(Запуск Junit4)
IinjectorProvider(Создаём Google Guice
инжектор)