まっつんです。前回は、Eclipse の Textual Modeling Framework を 言語ワークベンチ として使って DSL エディタを実装するために、DSL および DSL 処理系のプロセスフローを簡単に説明しました。
今回は Textual Modeling Framework を使って DSL エディタを実装します。
DSL の仕様
最初に DSL の仕様を以下のように定めておきます。
- Windows の INI ファイルなどで利用されている name = value 形式のテキストフォーマットであること
- value には文字列または他の name の参照を記述できること
- + 演算子によって複数の要素を連結できること
この DSL の使用例は以下のようになります。
foo = "AAA" bar = "BBB" baz = "CCC" qux = foo + bar + baz // "AAABBBCCC"
Xtext プロジェクトの作成
それではプロジェクトを作成してみましょう。新規作成ウィザードで [Xtext Project] を選択し、作成するプロジェクトの情報を以下のように入力します。
| 項目 | 値 | 説明 |
|---|---|---|
| Main Project name | jp.iteman.mydsl | メインプロジェクトの名称 |
| Language name | jp.iteman.MyDsl | 作成する言語の名称 |
| DSL-File extension | mydsl | DSL ファイルの拡張子 |
| Create generator project | オン | ジェネレータプロジェクトを生成するかどうか |
作成されるプロジェクトと役割は以下のとおりです。
| プロジェクト | 役割 |
|---|---|
| jp.iteman.mydsl | グラマーを定義する |
| jp.iteman.mydsl.ui | DSL エディタを提供する |
| jp.iteman.mydsl.generator | DSL スクリプトをセマンティックモデルに静的に変換する (今回は使用しない) |
DSL のグラマーを定義する
続いて DSL のグラマー (文法) を定義します。Textual Modeling Framework (以下、TMF) はグラマーの定義を起点としてレキサやパーサ、エディタといったさまざまな種類のコードを生成します。
グラマーは jp.iteman.mydsl/src/jp.iteman/MyDsl.xtext で定義します。今回の DSL のグラマーは以下のとおりです。
jp.iteman.mydsl/src/jp.iteman/MyDsl.xtext
grammar jp.iteman.MyDsl with org.eclipse.xtext.common.Terminals
generate myDsl "http://www.iteman.jp/MyDsl"
Ini :
(configurations+=Config)+;
Config :
name=ID '=' value=Expression;
ConfigRef :
ref=[Config] | value=STRING;
Expression :
TerminalExpression ({Operation.left=current} op='+' right=Expression)?;
TerminalExpression returns Expression:
'(' Expression ')' | {MethodValueLiteral} value=ConfigRef;
ノート: グラマー言語については「Xtext User Guid」の「2. The Grammar Language」をご覧ください。
DSL エディタを生成する
以上でグラマーの定義が完了し、エディタを生成できるようになりました。TMF は Modeling Workflow Engine (MWE) を使用してコード生成を行います。jp.iteman.mydsl/src/jp.iteman/GenerateMyDsl.mwe はコード生成のための MWE の定義ファイルです。
jp.iteman.mydsl/src/jp.iteman/GenerateMyDsl.mwe を右クリックし、[Run As] -> [MWE Workflow] をクリックすることでコード生成が行われます。このときコンソールビューにはコード生成の進行状況が表示されます。
DSL エディタを実行する
それではエディタを動かしてみましょう。最初に [Run] メニュー -> [Run Configurations...] をクリックします。次に Eclipse Application を作成し、[Run] ボタンで実行します。以上の操作で現在開発しているプラグインの実行用 Eclipse が起動します。
起動した Eclipse で適当なプロジェクトを作成し、拡張子が .mydsl のファイルを作成すると、自動生成されたエディタが起動します。
スクリーンショットからは、文字列の強調表示、入力の補完、アウトラインビューといったエディタに必要な機能が一通り揃っていることがわかります。もちろん、追加のコードを書くことでエディタの振る舞いを拡張することも可能です。
言語ワークベンチとしての TMF
筆者は Eclipse でテキストエディタを実装したことがありますが、これだけの機能を持つエディタを実装するのは簡単ではありません。TMF はグラマーを定義するだけでそれを生成することができます。TMF は外部 DSL エディタの実装コストを大幅に下げることができるものである、と言えるでしょう。
では、TMF を 言語ワークベンチ として評価するとどうでしょうか?
Martin Fowler 氏は記事「言語ワークベンチ」で 言語ワークベンチ の必要条件を以下のようにまとめています。
- ユーザが自由に新しい言語を定義できる。言語はそれぞれ完全に統合可能である。
- 一次情報ソースは、永続化された抽象形(persistent abstract representation)である。
- 言語設計者は、スキーマ、エディタ、ジェネレータの3つの部分に分けてDSLを定義する。
- 言語ユーザは、投影エディタ(projectional editor)でDSLを操作する。
- 言語ワークベンチは、不完全だったり矛盾だったりする情報を抽象形に永続化できる。
これらのうち 一次情報ソースは、永続化された抽象形(persistent abstract representation)である。 という点を TMF は明らかに満たしていません。
TMF の 1 次情報ソースは、テキスト表現の DSL スクリプトそのものであり、永続化された抽象形ではありません。言語ワークベンチ のスキーマはこの抽象形に対するグラマーを指しますが、TMF のスキーマはテキスト表現の DSL スクリプトに対するグラマーです。
ノート: ここでいう抽象形とは、DSL の AST あるいはセマンティックモデルを指していると考えられます。なお、TMF の抽象形は EMF モデルです。
ノート: JetBrains の Meta Programming System (最近 1.0 がリリースされました!) に関する記事 InfoQ: JetBrains のメタプログラミングシステムは言語指向プログラミングと DSL をサポート で、1 次情報ソースが永続化された抽象形でないことの欠点について、開発チームを率いている Konstantin Solomatov 氏の見解を読むことができます。
よって、TMF は 言語ワークベンチ の定義を満たしているとは言えません。これは大きな欠点でしょうか?
幸いにも Eclipse にはモデリングフレームワーク Eclipse Modeling Framework (EMF) と、それを基盤とするグラフィカルなモデリングフレームワーク Eclipse Graphical Modeling Framework (GMF) があります。
GMF は、グラフィカルな DSL エディタを作成するために使うことができますが、ここで中心となるのは DSL の抽象形であるセマンティックモデル (ドメインモデル) となります。GMF でエディタを生成するためのワークフローを見てください。
ノート: Piece Framework のプロダクト Piece_IDE にはグラフィカルなエディタでページフローを編集する機能があります。これは GMF ベースの DSL エディタの実例です。
GMF では抽象形および保存形として EMF モデルが使用されます。よって、GMF の 1 次情報ソースは永続化された抽象形です。そして TMF (Xtext) には EMF のリソース API が実装されており、動的または静的にテキストモデルと EMF モデルを相互変換することができます。
このことは TMF 単体では言語ワークベンチを構成できませんが、EMF モデルを起点にすることで GMF と TMF を統合できる可能性を示しています。
これが可能だとしたら TMF + GMF で言語ワークベンチを構成することができるでしょう。例えば、永続化された EMF モデルを TMF ベースのエディタで編集したり、GMF ベースのグラフィカルなエディタで編集する、そしてお互いの変更をリアルタイムに反映する、といったことが可能になるでしょう。
アイテマンでは、これらを実現するための具体的なアーキテクチャに関する調査を続けています。何か進展がありましたらブログでお伝えしたいと思います。
おわりに
DSL はドメインの可変点を表現し、具体的なシステムを発注するための指示書です。DSL のための環境である 言語ワークベンチは、ビジネスの現場で求められる継続的で進化的なプログラミングプラットフォームとして大きな可能性を秘めています。これは、従来のシステム開発のあり方を大きく変えるものになるかもしれません。TMF (そして GMF) を使うことで、そのような新しい世界の一端を垣間見ることができるでしょう。
使用したソフトウェアのバージョン
| Eclipse (Eclipse Modeling Tools) | 3.5 |
|---|---|
| TMF (Xtext) | 0.7.0 |
| ANTLR | 3.0.1 |
参考文献
トラックバック(0)
- このブログ記事のトラックバックURL:
