ひしだまの変更履歴

ひしだまHPの更新履歴。
主にTRPGリプレイの元ネタ集、プログラミング技術メモと自作ソフト、好きなゲームや音楽です。

第1回Asakusaソースコードリーディングの感想

2011-05-25 23:59:43 | PG(分散処理)

Asakusaソースコードリーディング(第一回)に行ってきましたので、その感想など。
資料: Ashigel CompilerInside of Asakusa DSL
Togetter:# AsakusaReading Asakusaソースコードリーディング(第一回)
ソースへのリンク:Asakusa SCR #1 - draft

(行ってみたら名簿に名前が無かった。やはり当日申し込んだから^^; そういう事もあるかもしれないとは思ったけど、zusaarで見たら席が空いていたので…すみません)

冒頭、ノーチラス・テクノロジーズの神林さんから挨拶。新しい会社を作ったと皆知ってる…!(笑) おめでとうございます。


さて本題だけど、Asakusaフレームワーク自体まだ使ったことないのに、やはりコンパイラの説明は厳しかった(爆)
でもコンパイラーと言いつつも、DSLによって解釈方式が全然違うのが面白かった。コンパイラーに興味がある人にとっては興味深い話だったのではないだろうか。

まず一般的な概要として、コンパイラーはSource Code→Abstract Syntax Tree(AST)→Abstract Semantic Graph(ASG)→Target Codeという順で生成していくのだそうだ。
ASTはソースコードと同じ構造をもつ木構造(DOMと同じ)。日本語だと抽象構文木
ASGはソースをまたがる参照情報等を付加した構造で、最適化の基盤ともなる。

あと、ソースを読み込んで(別言語の)ソースを出力するのは「コンパイル」と言うより「トランスレート(変換)」だそうだが、AsakusaDSL(Ashigelコンパイラ)ではコンパイルという言葉を使っている。
(ashigeruさんとしては、Ashigelコンパイラというのを口に出すのは恥ずかしいようですがw)


AsakusaFWにはOperator DSLとFlow DSLとBatch DSLがあるわけだが、新たにData Model Definition Language(DMDL)というのが加わったらしい。
AsakusaではRDB(MySQL)からデータを取ってくる(データ定義も取ってくる。ちなみにExcelにも出力できる)前提だったが、それ以外のデータも扱えるようにする為にデータ定義を行う言語だそうだ。

で、DMDLのコンパイルにはJavaCC(パーサージェネレーター)とJFlexを使ってパーサー(解析器)を作っている。
(JavaCCにも字句解析機能はあるが、JFlexの方が便利らしい)
ただしそのまま使うとコンパイルエラー時に詳細な情報(エラー位置とかエラー理由とか)が出しづらいので、解析時のスタックフレーム(フレームスタック?)を自前で保持してエラー理由を推定できるよう、ごりごりコーディングしているらしい。

Operator DSLはJava6の注釈プロセッサ(JSR-269。JDK1.5で言えばAPT)を使って解析している。注釈プロセッサは、javacにプラグインを追加するような感じで、コンパイル時にアノテーションに対して自前の処理を実施できる。Eclipseでもプロジェクトのプロパティーから「Javaコンパイラー」の「注釈処理」で注釈プロセッサを指定できる。
注釈プロセッサでは、アノテーションの付いたメソッド一覧を取得するのとかが簡単に出来るらしい。
Javaソースの解析自体はjavacがやってくれるので、自分では何もしなくていい。この辺りが既存言語上でDSLを作るメリット。
(注釈プロセッサでは、内部的にソースを出力できる。解釈されていないソースがあると自動的にコンパイルされ、収束する(解釈できるソースが無くなる)までそれが繰り返されるらしい。この間、一時的に整合性が取れずコンパイルエラー(警告)が発生することがあるが、これを抑止する方法が不明らしい)

Flow DSLは、記述されたJavaコードを実行するとグラフが作られる。(ここではJavaコードを実際に実行しているので、ユーザーがやろうと思えば何でも書ける)
Operator DSLでは、Flow DSLを生成する為のコードも生成している。
フローの段階?としてBatch・jobflow・stage(・MapReduce)があり、FlowGraphを作ってからStageGraphを作っている。現在のAsakusaFWではコンパイル時点でステージ(どういうMapReduceにするか)を決めてしまうが、理想的には実行時に(動的に)前ステージの結果(データ量とか)に応じて処理方法を変えたい。その場合、コンパイル時に(静的に)出来るのはFlowGraph生成までで、StageGraphは実行時に決めることになる。
IRという言葉も出ていたような気がするけど、もうこの辺りは理解不能(苦笑)

あと、DirectBatchCompilerというクラスはtestingとかいうパッケージの下に入っているらしい。元はテスト用に作られたという経緯らしいが、そのまんまリリースされちゃったとか^^;
まぁ試行錯誤してると色々あるよねぇ。ソースを見直してたらFIXMEというコメントを見つけちゃったりとかさ(笑)


これらのコンパイル(トランスレート)を実行するに当たり、具体的な処理はServiceLoader(SPI)によって外部から実装を追加するように作られているそうだ。

SPI(サービスプロバイダー)には聞き覚えがある。
JDK1.6のJDBCドライバーがClass.forNameを呼ばなくてよくなったのは、SPIを使ってドライバーの具象クラスを読み込むようになったからだよね。


最後にちらっと話題に出ていたのが、Hadoop以外のMapReduceの実装や、MapReduce以外の分散処理があまり注目されていないよね、という事。
そんなものが有名になってきたら、面白いけどまた勉強が大変になるなぁ^^;

ふう。自分の能力不足により、Asakusaフレームワークのコンパイラー自体について理解できたとは言えないけれども、コンパイラーの作り方やその周辺技術は勉強になった^^

ありがとうございました。

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする