xtext入門

38
©2014 Shintaro Hosoai Xtext 入入 入入 入入入 2014/3/29 SEA 入 入入入入入入入 西

Upload: shintaro-hosoai

Post on 19-Aug-2014

407 views

Category:

Engineering


3 download

DESCRIPTION

第56回SEA関西プロセス分科会で用いた講義資料です. DSL開発支援環境であるXtextについて解説しています. ここでは,Xtextの裏側の仕組みをメインに取り扱っています.

TRANSCRIPT

Page 1: Xtext入門

©2014 Shintaro Hosoai

Xtext 入門細合 晋太郎

2014/3/29 SEA 関西プロセス分科会

Page 2: Xtext入門

©2014 Shintaro Hosoai 2

DSL(Domain Specific Language)とは• 特定用途に限定した,独自言語• 一般的に他言語にマッピングして用いられる事が多い• 特定用途にしか利用できないが,抽象度が高く,より要件に近い表現ができる.

2014/3/29 SEA 関西プロセス分科会

AssemblerC

Java

DSL

汎用性

抽象度

Page 3: Xtext入門

©2014 Shintaro Hosoai 3

DSL のメリット• 生産性の向上• ドメイン分析• 特定のモデルしか書けない• プログラミングの知識があまりなくても書ける• ドメインを明確にする

• プログラミングというプログラマの暗黙知を形式知に• とはいえ,変換ルール,コードテンプレートは結局暗黙的になっちゃいますが・・.

2014/3/29 SEA 関西プロセス分科会

Page 4: Xtext入門

©2014 Shintaro Hosoai 4

DSL の分類

• 今回の Xtext は External Textual DSL を生成するためのフレームワークです.• Xtext は Java との親和性が高いので, Internal DSLに近い感覚で利用できます.

2014/3/29 SEA 関西プロセス分科会

Internal言語内 External独自処理系Textualテキスト形式 Rake(Ruby) Make ,

SQLGraphical図形式 Visual Studio? UML, SysML,

Matlab

Page 5: Xtext入門

©2014 Shintaro Hosoai 5

DSL 環境の構造

2014/3/29 SEA 関西プロセス分科会

DSL 定義

DSL

コード

テンプレートDSLエディタ

DSLパーサコードジェネレータ

DSLメタモデルモデル

Page 6: Xtext入門

©2014 Shintaro Hosoai 6

DSL の作り方• ドメイン知識が必要となるため,新規開発にはあまり向かない• 既存資産からパターンを抽出し,ドメインモデルと変換規則を作成する

2014/3/29 SEA 関西プロセス分科会

ドメイン固有のパターンの抽出 既存資産

DSL 定義 テンプレート

Page 7: Xtext入門

©2014 Shintaro Hosoai 7

Xtext

2014/3/29 SEA 関西プロセス分科会

Page 8: Xtext入門

©2014 Shintaro Hosoai

Xtext とは• Itemis 社のオープンソースプロジェクト

Eclipse の DSL 開発支援環境• 言語定義を元に Eclipse 上で動作する DSL エディタ, DSL パーサ,言語モデル,コードジェネレータ等を生成する• http://www.eclipse.org/Xtext/index.html

82014/3/29 SEA 関西プロセス分科会

Page 9: Xtext入門

©2014 Shintaro Hosoai 9

Xtext

2014/3/29 SEA 関西プロセス分科会

DSL 定義

DSL

コード

テンプレートDSLエディタ

DSLパーサコードジェネレータ

DSLメタモデルモデル

Page 10: Xtext入門

©2014 Shintaro Hosoai

Xtext 機能紹介

102014/3/29 SEA 関西プロセス分科会

Syntax Coloring Content Assist Validation and

Quick Fixes

Advanced Java

Integration

Integration with other

Eclipse tools

More IDE Features

Page 11: Xtext入門

©2014 Shintaro Hosoai 11

Xtext 構成

2014/3/29 SEA 関西プロセス分科会

EMFMDD 基盤

Xtend2Java を生成する軽量言語

MWE2モデルワークフローエンジン

XtextDSL 言語定義

Page 12: Xtext入門

©2014 Shintaro Hosoai 12

Xtext 構成

2014/3/29 SEA 関西プロセス分科会

Xtend2Java を生成する軽量言語

MWE2モデルワークフローエンジン

XtextDSL 言語定義

EMFMDD 基盤

Page 13: Xtext入門

©2014 Shintaro Hosoai 13

EMF ( Eclipse Modeling Framework)• Eclipse のモデリングフレームワーク• OMG の MDA に基づいた実装• 多くのモデリング技術の基盤となっている• MDA とは

2014/3/29 SEA 関西プロセス分科会

M3: メタメタモデルM2: メタモデルM1: モデルM0: インスタンス

メタモデルを定義するための,一番大本となるモデルMOF(Meta Object Facility)

モデルを定義するモデル, UML や SysML, その他 OMG の各種モデルがこのレベルで定義されているメタモデルで定義された記法に沿って記述されたモデル.UML に当てはめるなら,実際に描かれたクラス図などモデルに基づいた実体. UML であれば実装されたコードなど

この MOF が EMF で ecore として実装されている.ecore を基盤とすることで, MDA の多くの技術が利用可能に

Page 14: Xtext入門

©2014 Shintaro Hosoai 14

Eclipse Modeling Projects

2014/3/29 SEA 関西プロセス分科会

EMF

モデル入力( DSL )TextualXtext

GraphicalGMF

Graphiti

モデル変換ATLQVTQVTd

http://projects.eclipse.org/list-of-projects

コード生成Acceleo

JET2Xpand

その他EMF Diff

EMF QueryAMW

MoDiscoUML2

PapyrusOCL

SiriusSphinx

VIATRA2Requirement

BPMN2Epsilon

Ecore ToolsTexo   ...

Page 15: Xtext入門

©2014 Shintaro Hosoai 15

Xtext の EMF• 主に言語のメタモデル生成.このメタモデル・メタモデル実装( Java )をベースに各種プラグインが形成される

2014/3/29 SEA 関西プロセス分科会

言語定義( .xtext )言語メタモデル( .ecore )

言語メタモデル実装( .java )

Xtext の生成プラグイン

Page 16: Xtext入門

©2014 Shintaro Hosoai 16

Xtext 構成

2014/3/29 SEA 関西プロセス分科会

EMFMDD 基盤

MWE2モデルワークフローエンジン

XtextDSL 言語定義

Xtend2Java を生成する軽量言語

Page 17: Xtext入門

©2014 Shintaro Hosoai 17

Xtend2• Xtext で作られた Java を生成する LL• Java のかゆい所に手が届く,とても便利な言語• 書いたそばから生成→コンパイルまで行ってくれるので, Java とシームレスに利用可能• Xtext でも様々な用途で用いられている• 主要機能• 動的型付け(ただしコンパイル時に型決定なので安心)• ラムダ式,拡張関数,拡張 Switch• テンプレート記述• → マニュアル参照

2014/3/29 SEA 関西プロセス分科会

Page 18: Xtext入門

©2014 Shintaro Hosoai 18

コードテンプレート

2014/3/29 SEA 関西プロセス分科会

def toJavaCode(Statemachine sm) '''  import java.io.BufferedReader;  import java.io.IOException;  import java.io.InputStreamReader;

  public class «sm.eResource.className» {

   public static void main(String[] args) {    new «sm.eResource.className»().run();   }   «FOR c : sm.commands»    «c.declareCommand»   «ENDFOR»   protected void run() {    boolean executeActions = true;    String currentState = "«sm.states.head?.name»";    String lastEvent = null;    while (true) {

テンプレート

public class signal {  public static void main(String[] args) {   new signal().run();  }  protected void doLightBlue() {   System.out.println("Executing command  }  protected void doLightYellow() {   System.out.println("Executing command     }  protected void doLightRed() {   System.out.println("Executing command   }protected void run() {

生成コード

Page 19: Xtext入門

©2014 Shintaro Hosoai 19

Xtext 構成

2014/3/29 SEA 関西プロセス分科会

EMFMDD 基盤

Xtend2Java を生成する軽量言語

XtextDSL 言語定義

MWE2モデルワークフローエンジン

Page 20: Xtext入門

©2014 Shintaro Hosoai 20

MWE2• ワークフローエンジン.これも Xtext で書かれてます.• モデル駆動開発の主要な作業(ワーク)をワークフローの形で記述できる• 例えば• DSL ファイルの読み込み,パース,モデル変換,コード生成など• Xtext の言語生成を行う際もこの MWE2 のスクリプトを起動して言語環境の生成を行う.

2014/3/29 SEA 関西プロセス分科会

Page 21: Xtext入門

©2014 Shintaro Hosoai 21

MWE2 例

2014/3/29 SEA 関西プロセス分科会

Workflow { bean = StandaloneSetup { ... } component = DirectoryCleaner {   directory = "${runtimeProject}/src-gen" } component = Generator {  pathRtProject = runtimeProject  pathUiProject = "${runtimeProject}.ui"  pathTestProject = "${runtimeProject}.tests"  projectNameRt = projectName  projectNameUi = "${projectName}.ui"  encoding = encoding  language = auto-inject {   uri = grammarURI       fragment = grammarAccess.GrammarAccessFragment auto-inject {}   ...

フロー例Standalone

Setup

DirectoryCleaner

Generator

Page 22: Xtext入門

©2014 Shintaro Hosoai 22

Xtext 構成

2014/3/29 SEA 関西プロセス分科会

EMFMDD 基盤

Xtend2Java を生成する軽量言語

MWE2モデルワークフローエンジン

XtextDSL 言語定義

Page 23: Xtext入門

©2014 Shintaro Hosoai 23

Xtext• 言語定義と言語環境の生成.エディタの生成• 言語定義言語の Xtext 自体もまた Xtext で作られている• Xtext は拡張 BNF 風の言語定義言語• 再帰下降型構文解析• EMF のモデルへ変換する字句解析器,構文解析器が自動生成される

2014/3/29 SEA 関西プロセス分科会

Page 24: Xtext入門

©2014 Shintaro Hosoai

Xtext 構造grammar org.eclipse.xtext.example.fowlerdsl.Statemachine with  org.eclipse.xtext.common.Terminals

generate statemachine "http://www.eclipse.org/xtext/example/fowlerdsl/Statemachine"

Statemachine : {Statemachine}   ('events'    events+=Event+    'end')?   ('resetEvents'    resetEvents+=[Event]+    'end')?   ('commands'    commands+=Command+    'end')?   states+=State*;

terminal MYID:'A''0'..'9';

言語名宣言と言語Mixin

言語モデル宣言Parser Rule/言語構造定義

lexis/語彙定義

初めのうちは,上二つは自動生成ままで利用するのがよい

Event:   name=ID; ...

2014/3/29 SEA 関西プロセス分科会 24

Page 25: Xtext入門

©2014 Shintaro Hosoai

Parser RulesState:   'state' name=ID   ('actions' '{' actions+=[Command]+ '}')?   transitions+=Transition*   'end';

state myState actions { myCommand1 myCommand2 } event2 => myState2 event3 => myState3end

Transition:   event=[Event] '=>' state=[State];

DSL 定義

DSL 例

2014/3/29 SEA 関西プロセス分科会 25

Page 26: Xtext入門

©2014 Shintaro Hosoai

Parser RulesState:   'state' name=ID   ('actions' '{' actions+=[Command]+ '}')?   transitions+=Transition*   'end';

state myState actions { myCommand1 myCommand2 } event2 => myState2 event3 => myState3end

Transition:   event=[Event] '=>' state=[State];

DSL 定義

DSL 例

定義名:~‘;’までが一つのルールとなる.この定義名のモデルが生成される( Returns を指定しない場合)

: State

: Transition: Transition

: Commandactions

transitions

: Command

2014/3/29 SEA 関西プロセス分科会 26

Page 27: Xtext入門

©2014 Shintaro Hosoai

Parser RulesState:   'state' name=ID   ('actions' '{' actions+=[Command]+ '}')?   transitions+=Transition*   'end';

state myState actions { myCommand1 myCommand2 } event2 => myState2 event3 => myState3end

Transition:   event=[Event] '=>' state=[State];

DSL 定義

DSL 例

’’で区切った部分は語彙として定義される

2014/3/29 SEA 関西プロセス分科会 27

Page 28: Xtext入門

©2014 Shintaro Hosoai

Parser RulesState:   'state' name=ID   ('actions' '{' actions+=[Command]+ '}')?   transitions+=Transition*   'end';

state myState actions { myCommand1 myCommand2 } event2 => myState2 event3 => myState3end

Transition:   event=[Event] '=>' state=[State];

DSL 定義

DSL 例

変数は,属性として生成される.割り当てに応じて = :単体, += : Listとして生成State

name : IDactions : List<Command>

transitions:List<Transition>Transition

event : Eventstate : State

2014/3/29 SEA 関西プロセス分科会 28

Page 29: Xtext入門

©2014 Shintaro Hosoai

Parser RulesState:   'state' name=ID   ('actions' '{' actions+=[Command]+ '}')?   transitions+=Transition*   'end';

state myState actions { myCommand1 myCommand2 } event2 => myState2 event3 => myState3end

Transition:   event=[Event] '=>' state=[State];

DSL 定義

DSL 例[] で指定した要素は name によりでインスタンスを参照する.このため参照される Rule には name=IDを持つ必要がある.例では State,Event,Command は参照可Transition は name=ID を持たないので,参照出来ない.

割り当てに用いることが出来るのは,・ Terminal Rule  ( ex: ID )・ Parser Rule ( ex: Transition )・ Parser Rule の実体への参照( ex: [Command] )

2014/3/29 SEA 関西プロセス分科会 29

Page 30: Xtext入門

©2014 Shintaro Hosoai

Parser RulesState:   'state' name=ID   ('actions' '{' actions+=[Command]+ '}')?   transitions+=Transition*   'end';

state myState actions { myCommand1 myCommand2 } event2 => myState2 event3 => myState3end

Transition:   event=[Event] '=>' state=[State];

DSL 定義

DSL 例

繰り返し指定*:0以上+:1以上?:0 or1():グループ化

actions 句はあってもなくてもよい. action は空白区切りで1以上繰り返し指定可能transition 句は 0 回以上なので,なくてもよい1以上の繰り返し指定を行う場合は+= で割り当てる.

2014/3/29 SEA 関西プロセス分科会 30

Page 31: Xtext入門

©2014 Shintaro Hosoai 31

まとめ

2014/3/29 SEA 関西プロセス分科会

DSL 定義

DSL

コード

テンプレートDSLエディタ

DSLパーサコードジェネレータ

DSLメタモデルモデル

XtendEMFXtext

MWE2

Page 32: Xtext入門

©2014 Shintaro Hosoai

Xtext Project Sample

2014/3/29 SEA 関西プロセス分科会 32

Page 33: Xtext入門

©2014 Shintaro Hosoai 33

DSL エディタ生成までの流れ

2014/3/29 SEA 関西プロセス分科会

New Xtext ProjectWizard

①ひな形プロジェクト群の生成

*.tests*.ui *.sdk

Xtext Project

②言語定義の追加

言語定義言語生成ワークフロー

Page 34: Xtext入門

©2014 Shintaro Hosoai 34

生成されるプロジェクト• projectname言語定義とランタイムコンポーネント( Parser,

Lexer, Linker, validation )• projectname.testsユニットテスト用プロジェクト• projectname.uiエディタ機能の拡張用プロジェクト(コンテンツアシスト,ラベル,アウトライン,クイックフィックス)• projectname.sdk

Xtext以外の拡張を行う際のひな形2014/3/29 SEA 関西プロセス分科会

Page 35: Xtext入門

©2014 Shintaro Hosoai 35

プロジェクト詳細• ProjectName• src : ユーザが定義するソース群

• * : 言語定義• *.formatting : コードフォーマット• *.generator : コード生成定義• *.jvmmodel : Java連携• *.scoping : 言語要素のスコープコントロール• *.validation : バリデーション機能

• src-gen : ワークフローや ecore から自動生成されるコード群• xtend-gen : Xtend から自動生成されるコード群• model : 言語定義から生成される ecore• その他 : plugin.xml 等

2014/3/29 SEA 関西プロセス分科会

最初の内はこの二つから触るのがよい

Page 36: Xtext入門

©2014 Shintaro Hosoai

grammar org.eclipse.xtext.example.fowlerdsl.Statemachine with  org.eclipse.xtext.common.Terminalsgenerate statemachine "http://www.eclipse.org/xtext/example/fowlerdsl/Statemachine"

Statemachine : {Statemachine}   ('events'    events+=Event+    'end')?   ('resetEvents'    resetEvents+=[Event]+    'end')?   ('commands'    commands+=Command+    'end')?   states+=State*;

Event:   name=ID;

Command:   name=ID;

State:   'state' name=ID   ('actions' '{' actions+=[Command]+ '}')?   transitions+=Transition*   'end';

Transition:   event=[Event] '=>' state=[State];

First Example(1) : Xtext

Statemachine

Event Command State

Transition

events commands states

event statetransitions

actions

*** *

*

11

New > Example, Xtext Examples > Xtext Statemachine Example

362014/3/29 SEA 関西プロセス分科会

Page 37: Xtext入門

©2014 Shintaro Hosoai

DSL をパースして生成されるモデル

DSL イメージFirst Example(2) : DSLevents toBlue toYellow toRedend

commands lightBlue lightYellow lightRedend

state blue actions { lightBlue } toYellow=>yellowendstate yellow actions { lightRed } toRed=>redendstate red actions { lightRed } toBlue=>blueend

blueentry/lightBlue

yellowentry/lightYellow

redentry/lightRed

toBlue

toYellow

toRed

toBlue:EventtoYellow:Event

toRed:Event

lightBlue:CommandlightYellow:Command

lightRed:Command

blue:Stateyellow:State

red:StatetoBlue->blue:TransitiontoYellow->yellow:Transition

toRed->red:Transition

:Statemachine

→ のようなステートマシンをDSL として入力

Xtext によるパース

2014/3/29 SEA 関西プロセス分科会 37

Page 38: Xtext入門

©2014 Shintaro Hosoai

First Example(3) : Code Generate

DSL をパースして生成されるモデルtoBlue:Event

toYellow:Even

t

toRed:Event

lightBlue:Comman

d

lightYellow:Comma

nd

lightRed:Command

blue:State

yellow:Stat

e

red:Stat

e

toBlue->blue:Transition

toYellow-

>yellow:Transitio

n

2014/3/29 SEA 関西プロセス分科会 38

生成モデルdef toJavaCode(Statemachine sm) '''  import java.io.BufferedReader;  import java.io.IOException;  import java.io.InputStreamReader;

  public class «sm.eResource.className» {

   public static void main(String[] args) {    new «sm.eResource.className»().run();   }   «FOR c : sm.commands»    «c.declareCommand»   «ENDFOR»   protected void run() {    boolean executeActions = true;    String currentState = "«sm.states.head?.name»";    String lastEvent = null;    while (true) {

テンプレートpublic class signal {  public static void main(String[] args) {   new signal().run();  }  protected void doLightBlue() {   System.out.println("Executing command  }  protected void doLightYellow() {   System.out.println("Executing command     }  protected void doLightRed() {   System.out.println("Executing command   }protected void run() {

生成コード