Xtext入門
Upcoming SlideShare
Loading in...5
×
 

Xtext入門

on

  • 362 views

第56回SEA関西プロセス分科会で用いた講義資料です. ...

第56回SEA関西プロセス分科会で用いた講義資料です.
DSL開発支援環境であるXtextについて解説しています.

ここでは,Xtextの裏側の仕組みをメインに取り扱っています.

Statistics

Views

Total Views
362
Views on SlideShare
361
Embed Views
1

Actions

Likes
3
Downloads
5
Comments
0

1 Embed 1

http://www.slideee.com 1

Accessibility

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Xtext入門 Xtext入門 Presentation Transcript

  • ©2014 Shintaro Hosoai Xtext入門 細合 晋太郎 2014/3/29 SEA関西プロセス分科会
  • ©2014 Shintaro Hosoai DSL(Domain Specific Language)とは • 特定用途に限定した,独自言語 • 一般的に他言語にマッピングして用いられる事 が多い • 特定用途にしか利用できないが, 抽象度が高く,より要件 に近い表現ができる. 22014/3/29 SEA関西プロセス分科会 Assembler C Java DSL 汎用性 抽 象 度
  • ©2014 Shintaro Hosoai DSLのメリット • 生産性の向上 • ドメイン分析 • 特定のモデルしか書けない • プログラミングの知識があまりなくても書ける • ドメインを明確にする • プログラミングというプログラマの暗黙知を形 式知に • とはいえ,変換ルール,コードテンプレートは結局 暗黙的になっちゃいますが・・. 32014/3/29 SEA関西プロセス分科会
  • ©2014 Shintaro Hosoai DSLの分類 • 今回のXtextはExternal Textual DSLを生成するた めのフレームワークです. • XtextはJavaとの親和性が高いので,Internal DSL に近い感覚で利用できます. 42014/3/29 SEA関西プロセス分科会 Internal 言語内 External 独自処理系 Textual テキスト形式 Rake(Ruby) Make, SQL Graphical 図形式 Visual Studio? UML, SysML, Matlab
  • ©2014 Shintaro Hosoai DSL環境の構造 52014/3/29 SEA関西プロセス分科会 DSL定義 DSL コー ド テンプレー ト DSL エディ タ DSL パーサ コード ジェネ レータ DSL メタモデ ル モデ ル
  • ©2014 Shintaro Hosoai DSLの作り方 • ドメイン知識が必要となるため,新規開発には あまり向かない • 既存資産からパターンを抽出し,ドメインモデ ルと 変換規則を作成する 62014/3/29 SEA関西プロセス分科会 ドメイン固有の パターンの抽出 既存資産 DSL定義 テンプレー ト
  • ©2014 Shintaro Hosoai Xtext 2014/3/29 SEA関西プロセス分科会 7
  • ©2014 Shintaro Hosoai Xtextとは • Itemis社のオープンソースプロジェクト EclipseのDSL開発支援環境 • 言語定義を元にEclipse上で動作するDSLエディ タ,DSLパーサ,言語モデル,コードジェネ レータ等を生成する • http://www.eclipse.org/Xtext/index.html 82014/3/29 SEA関西プロセス分科会
  • ©2014 Shintaro Hosoai Xtext 92014/3/29 SEA関西プロセス分科会 DSL定義 DSL コー ド テンプレー ト DSL エディ タ DSL パーサ コード ジェネ レータ DSL メタモデ ル モデ ル
  • ©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
  • ©2014 Shintaro Hosoai Xtext構成 112014/3/29 SEA関西プロセス分科会 EMF MDD基盤 Xtend2 Javaを生成す る軽量言語 MWE2 モデルワーク フローエンジ ン Xtext DSL言語定義
  • ©2014 Shintaro Hosoai Xtext構成 122014/3/29 SEA関西プロセス分科会 Xtend2 Javaを生成す る軽量言語 MWE2 モデルワーク フローエンジ ン Xtext DSL言語定義 EMF MDD基盤
  • ©2014 Shintaro Hosoai EMF(Eclipse Modeling Framework) • Eclipseのモデリングフレームワーク • OMGのMDAに基づいた実装 • 多くのモデリング技術の基盤となっている • MDAとは 132014/3/29 SEA関西プロセス分科会 M3:メタメタモデ ル M2:メタモデル M1:モデル M0:インスタンス メタモデルを定義するための,一番大本となるモデル MOF(Meta Object Facility) モデルを定義するモデル,UMLやSysML,その他OMGの各種 モデルがこのレベルで定義されている メタモデルで定義された記法に沿って記述されたモデル. UMLに当てはめるなら,実際に描かれたクラス図など モデルに基づいた実体.UMLであれば実装されたコードなど このMOFがEMFでecoreとして実装されている. ecoreを基盤とすることで,MDAの多くの技術が利用可能に
  • ©2014 Shintaro Hosoai Eclipse Modeling Projects 142014/3/29 SEA関西プロセス分科会 EMF モデル入力 (DSL) Textual Xtext Graphical GMF Graphiti モデル変換 ATL QVT QVTd http://projects.eclipse.org/list-of-projects コード生成 Acceleo JET2 Xpand その他 EMF Diff EMF Query AMW MoDisco UML2 Papyrus OCL Sirius Sphinx VIATRA2 Requirement BPMN2 Epsilon Ecore Tools Texo ...
  • ©2014 Shintaro Hosoai XtextのEMF • 主に言語のメタモデル生成.このメタモデル・ メタモデル実装(Java)をベースに各種プラグ インが形成される 152014/3/29 SEA関西プロセス分科会 言語定義 (.xtext) 言語メタモデ ル (.ecore) 言語メタモデル 実装 (.java) Xtextの生成プラグイン
  • ©2014 Shintaro Hosoai Xtext構成 162014/3/29 SEA関西プロセス分科会 EMF MDD基盤 MWE2 モデルワーク フローエンジ ン Xtext DSL言語定義 Xtend2 Javaを生成す る軽量言語
  • ©2014 Shintaro Hosoai Xtend2 • Xtextで作られたJavaを生成するLL • Javaのかゆい所に手が届く,とても便利な言語 • 書いたそばから生成→コンパイルまで行ってく れるので,Javaとシームレスに利用可能 • Xtextでも様々な用途で用いられている • 主要機能 • 動的型付け(ただしコンパイル時に型決定なので安 心) • ラムダ式,拡張関数,拡張Switch • テンプレート記述 • →マニュアル参照 172014/3/29 SEA関西プロセス分科会
  • ©2014 Shintaro Hosoai コードテンプレート 182014/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() { 生成コード
  • ©2014 Shintaro Hosoai Xtext構成 192014/3/29 SEA関西プロセス分科会 EMF MDD基盤 Xtend2 Javaを生成す る軽量言語 Xtext DSL言語定義 MWE2 モデルワーク フローエンジ ン
  • ©2014 Shintaro Hosoai MWE2 • ワークフローエンジン.これもXtextで書かれ てます. • モデル駆動開発の主要な作業(ワーク)をワー クフローの形で記述できる • 例えば • DSLファイルの読み込み,パース,モデル変 換,コード生成など • Xtextの言語生成を行う際もこのMWE2のスクリ プトを起動して言語環境の生成を行う. 202014/3/29 SEA関西プロセス分科会
  • ©2014 Shintaro Hosoai MWE2例 212014/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 Directory Cleaner Generator
  • ©2014 Shintaro Hosoai Xtext構成 222014/3/29 SEA関西プロセス分科会 EMF MDD基盤 Xtend2 Javaを生成す る軽量言語 MWE2 モデルワーク フローエンジ ン Xtext DSL言語定義
  • ©2014 Shintaro Hosoai Xtext • 言語定義と言語環境の生成.エディタの生成 • 言語定義言語のXtext自体もまたXtextで作られ ている • Xtextは拡張BNF風の言語定義言語 • 再帰下降型構文解析 • EMFのモデルへ変換する字句解析器,構文解析 器が自動生成される 232014/3/29 SEA関西プロセス分科会
  • ©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
  • ©2014 Shintaro Hosoai Parser Rules State: 'state' name=ID ('actions' '{' actions+=[Command]+ '}')? transitions+=Transition* 'end'; state myState actions { myCommand1 myCommand2 } event2 => myState2 event3 => myState3 end Transition: event=[Event] '=>' state=[State]; DSL定義 DSL例 2014/3/29 SEA関西プロセス分科会 25
  • ©2014 Shintaro Hosoai Parser Rules State: 'state' name=ID ('actions' '{' actions+=[Command]+ '}')? transitions+=Transition* 'end'; state myState actions { myCommand1 myCommand2 } event2 => myState2 event3 => myState3 end Transition: event=[Event] '=>' state=[State]; DSL定義 DSL例 定義名:~‘;’までが一つのルールとなる. この定義名のモデルが生成される (Returnsを指定しない場合) :State :Transition:Transition :Commandactions transitions :Command 2014/3/29 SEA関西プロセス分科会 26
  • ©2014 Shintaro Hosoai Parser Rules State: 'state' name=ID ('actions' '{' actions+=[Command]+ '}')? transitions+=Transition* 'end'; state myState actions { myCommand1 myCommand2 } event2 => myState2 event3 => myState3 end Transition: event=[Event] '=>' state=[State]; DSL定義 DSL例 ’’で区切った部分は語彙として定義される 2014/3/29 SEA関西プロセス分科会 27
  • ©2014 Shintaro Hosoai Parser Rules State: 'state' name=ID ('actions' '{' actions+=[Command]+ '}')? transitions+=Transition* 'end'; state myState actions { myCommand1 myCommand2 } event2 => myState2 event3 => myState3 end Transition: event=[Event] '=>' state=[State]; DSL定義 DSL例 変数は,属性として生成される. 割り当てに応じて =:単体,+=:List として生成 State name : ID actions : List<Command> transitions:List<Transition> Transition event : Event state : State 2014/3/29 SEA関西プロセス分科会 28
  • ©2014 Shintaro Hosoai Parser Rules State: 'state' name=ID ('actions' '{' actions+=[Command]+ '}')? transitions+=Transition* 'end'; state myState actions { myCommand1 myCommand2 } event2 => myState2 event3 => myState3 end 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
  • ©2014 Shintaro Hosoai Parser Rules State: 'state' name=ID ('actions' '{' actions+=[Command]+ '}')? transitions+=Transition* 'end'; state myState actions { myCommand1 myCommand2 } event2 => myState2 event3 => myState3 end Transition: event=[Event] '=>' state=[State]; DSL定義 DSL例 繰り返し指定 *:0以上 +:1以上 ?:0or1 ():グループ化 actions句はあってもなくてもよい. actionは空白区切りで1以上繰り返し指 定可能 transition句は0回以上なので,なくても よい 1以上の繰り返し指定を行う場合は +=で割り当てる. 2014/3/29 SEA関西プロセス分科会 30
  • ©2014 Shintaro Hosoai まとめ 312014/3/29 SEA関西プロセス分科会 DSL定義 DSL コー ド テンプレー ト DSL エディ タ DSL パーサ コード ジェネ レータ DSL メタモデ ル モデ ル XtendEMFXtext MWE2
  • ©2014 Shintaro Hosoai Xtext Project Sample 2014/3/29 SEA関西プロセス分科会 32
  • ©2014 Shintaro Hosoai DSLエディタ生成までの流れ 332014/3/29 SEA関西プロセス分科会 New Xtext Project Wizard ①ひな形プロジェクト群の生成 *.tests*.ui *.sdk Xtext Project ②言語定義の追加 言語定義 言語生成 ワークフ ロー
  • ©2014 Shintaro Hosoai 生成されるプロジェクト • projectname 言語定義とランタイムコンポーネント (Parser, Lexer, Linker, validation) • projectname.tests ユニットテスト用プロジェクト • projectname.ui エディタ機能の拡張用プロジェクト(コンテン ツアシスト,ラベル,アウトライン,クイック フィックス) • projectname.sdk Xtext以外の拡張を行う際のひな形 342014/3/29 SEA関西プロセス分科会
  • ©2014 Shintaro Hosoai プロジェクト詳細 • ProjectName • src : ユーザが定義するソース群 • * : 言語定義 • *.formatting : コードフォーマット • *.generator : コード生成定義 • *.jvmmodel : Java連携 • *.scoping : 言語要素のスコープコントロール • *.validation : バリデーション機能 • src-gen : ワークフローやecoreから自動生成 されるコード群 • xtend-gen : Xtendから自動生成されるコード群 • model : 言語定義から生成されるecore • その他 : plugin.xml等 352014/3/29 SEA関西プロセス分科会 最初の内はこの二つ から触るのがよい
  • ©2014 Shintaro Hosoai 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*; 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 state transitions actions *** * * 11 New > Example, Xtext Examples > Xtext Statemachine Example 362014/3/29 SEA関西プロセス分科会
  • ©2014 Shintaro Hosoai DSLをパースして生成されるモデル DSLイメージ First Example(2):DSL events toBlue toYellow toRed end commands lightBlue lightYellow lightRed end state blue actions { lightBlue } toYellow=>yellow end state yellow actions { lightRed } toRed=>red end state red actions { lightRed } toBlue=>blue end blue entry/lightBlue yellow entry/lightYellow red entry/lightRed toBlue toYellow toRed toBlue:Event toYellow:Event toRed:Event lightBlue:Command lightYellow:Command lightRed:Command blue:State yellow:State red:State toBlue->blue:Transition toYellow->yellow:Transition toRed->red:Transition :Statemachine →のような ステートマシンを DSLとして入力 Xtextによる パース 2014/3/29 SEA関西プロセス分科会 37
  • ©2014 Shintaro Hosoai First Example(3):Code Generate 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() { 生成コード