110 likes | 277 Vues
統合開発環境のための プログラミング言語拡張 フレームワーク. 理学部 情報科学科 05_22951 松本 久志 指導教員 千葉滋. 言語拡張システムの必要性. 言語拡張を容易にするためのシステム ドメイン固有言語の作成 例 : O/R マッピング 既存言語の補填 例 : Open class コンパイラのためのシステム Polyglot [Myers ら ‘2003] JastAdd [Hedin ら ‘2003]. @ Refines ( A.class ) class B { void hoge() { .. } }.
E N D
統合開発環境のためのプログラミング言語拡張フレームワーク統合開発環境のためのプログラミング言語拡張フレームワーク 理学部 情報科学科 05_22951 松本 久志 指導教員 千葉滋
言語拡張システムの必要性 • 言語拡張を容易にするためのシステム • ドメイン固有言語の作成 • 例 : O/Rマッピング • 既存言語の補填 • 例 : Open class • コンパイラのためのシステム • Polyglot [Myers ら ‘2003] • JastAdd [Hedin ら ‘2003] @Refines(A.class) class B { void hoge() { .. } }
統合開発環境のための言語拡張システム • 統合開発環境への対応 • 現在ではコンパイラの提供だけでは不十分 • 従来技術 Polyglot, JastAdd など • 編集時の支援がない • 対話的なエラー報告 • Eclipseでは編集時に専用の処理
提案 : 編集時のエラー出力を操作するメタオブジェクトプロトコル(MOP) • 言語拡張をメタオブジェクトで記述 • 編集時とコンパイル時の2つのMOP • 編集時メタオブジェクト • 編集時に出力するエラーを制御 • コンパイル時メタオブジェクト • ソースコード変換で言語拡張を実装
編集時のMOPの動作 • エラーの出力を操作 • 必要のないエラーを除去 • 新たに必要なエラーを追加 • ソース変換は行わない • 厳密なエラー解析はコンパイル時に行えば良い @Refines(A.class) class B { void hoge() { .. } } class A {} @Refines(A.class) class B { void hoge() { .. } } class A {}
コンパイル時のMOPの動作 • 拡張言語のソースコードを変換 • 文字列としての変換 • ASTを利用した変換 • 元の言語の構文解析器を用いてASTを生成 • 変換後既存のコンパイラでコンパイル @Refines(A.class) class B { void hoge() { .. } } class A {} class A { void hoge() { .. } }
実装 • EclipseのJava開発環境を拡張可能に • JDTプラグインを拡張 • 言語拡張者の作業 • メタオブジェクトのメソッドを上書き • 編集時: finalizeProblems • 引数:ソースファイルの解析結果 • 標準JDTが作成、発見したエラー情報を含む • コンパイル時: convertSources • 抽象構文木を取り出し変形 エラー出力の操作 ソースの変換
適用例 @Refinesによるopen classの機構 • 言語拡張に由来したエラーの除去 • 拡張された言語のコンパイル及び実行が可能 • エラー操作は18行ソース変換は32行の記述で実現
記述例 @Refinesによるopen classの機構 編集時のエラー出力の操作 コンパイル時のソース変換 @Override public void convertSources() { for(CTUnit unit : CTMOP.getUnits()) { /* ビジターパターンを用いて @Refinesアノテーションを検索 */ unit.getCompilationUnit().accept(new ASTVisitor() { public boolean visit(SingleMemberAnnotation node) { if(node.getTypeName().toString().equals(“Refines”) && node.getParent() instanceof TypeDeclaration) { : // フィールド及びメソッドのコピー } } } } } @Override public void finalizeProblems(CompilationUnitDeclaration u) { List<CategorizedProblem> newList = new LinkedList<CategorizedProblem>(); CompilationResult result = u.compilationResult(); for(CategorizedProblem problem : result.problems){ if(problem.isError()) { if(problem.getCategoryID() == CategorizedProblem.CAT_TYPE) { // @Refinesアノテーションに関するエラーは無視 if(problem.getArguments()[0].equals(“Refines”)) continue; } : // 他のエラー判定条件 newList.add(problem); } } unit.compilationResult().problems = newList.toArray(new CategorizedProblem[newList.size()]); }
関連研究 • 拡張可能コンパイラ • Polyglot [Myers ら ‘2003] • 拡張しやすいJavaフロントエンドフレームワーク • JastAdd [Hedin ら ‘2003] • 属性文法による意味解析 • 差分のみの記述で構文拡張可能 • 編集時メタオブジェクト • “Expressive programs through presentation extension”[Eisenberg ら ‘2007] • 編集時とコンパイル時のMOPを提供 • 編集時のソースコードの表示を制御
まとめと今後の課題 • 統合開発環境に対応した言語拡張フレームワークの提案 • コンパイル時及び編集時のMOPを提供 • 編集時にエラー出力の操作を行う • コンパイル時にソース変換を行う • JDTを拡張して実装 • 今後の課題 • ASTの操作の簡易化 • エラーの判別方法の確立