内部ドメイン専用言語支援のため の 型に連動した字句・構文ルールの 変更機構 理学部 情報科学科 千葉研究室 07_02363 市川 和央 指導教員 千葉 滋 教授 1.

Slides:



Advertisements
Similar presentations
アルゴリズムとプログラミン グ (Algorithms and Programming) 第6回:クラスとインスタンス クラスの宣言 アクセス修飾子 インスタンスの生成 (new キーワード) this キーワード フィールドとメソッドの実際の定義と使い 方 クラスの宣言 アクセス修飾子 インスタンスの生成.
Advertisements

2.5 プログラムの構成要素 (1)文字セット ① ASCII ( American Standard Code for Interchange ) JIS コードと同じ ② EBCDIC ( Extended Binary Coded Decimal for Information Code ) 1.
ユーザ定義演算子による 内部 DSL の構成法 市川 和央 千葉 滋 東京工業大学大学院 1. Domain Specific Language (DSL) 用途に応じたミニ言語 select name from register where age < 30 SQL hello : hello.c.
プログラミング言語論 第10回(演習) 情報工学科 木村昌臣   篠埜 功.
Problem J: いにしえの数式 問題作成・解説: 北村 解答作成協力: 八森.
情報理工学部 情報システム工学科 ラシキアゼミ 3年 H 井奈波 和也
情報理工学部 情報システム工学科 3年 H 井奈波 和也
密な演算子呼び出しで実現した 内部DSLの前処理による 実行速度改善の試み
Javaのための暗黙的に型定義される構造体
12.3,E,-15, 12.3,E5,+,=, >,<,…,
プログラミング基礎I(再) 山元進.
Myoungkyu Song and Eli Tilevich 発表者: 石尾 隆(大阪大学)
プログラミング言語論 第6回 型 情報工学科 篠埜 功.
第2回:Javaの変数と型の宣言 プログラミングII 2007年10月2日.
プログラミング言語論 第4回 式の構文、式の評価
言語処理系(5) 金子敬一.
プログラミング論 II 電卓,逆ポーランド記法電卓
  【事例演習6】  数式インタプリタ      解 説     “インタプリタの基本的な仕組み”.
リファクタリングのための 変更波及解析を利用した テスト支援ツールの提案
同期的にアドバイスを活性化できる分散動的アスペクト指向システム
メソッド名とその周辺の識別子の 相関ルールに基づくメソッド名変更支援手法
アスペクト指向プログラミングを用いたIDSオフロード
プログラミング言語論 第2回 情報工学科 篠埜 功.
細かい粒度でコードの再利用を可能とするメソッド内メソッドのJava言語への導入
JDBC J2EE I 第4回 /
識別子の命名支援を目的とした動詞-目的語関係の辞書構築
細かい粒度で コードの再利用を可能とする メソッド内メソッドと その効率の良い実装方法の提案
東京工科大学 コンピュータサイエンス学部 亀田弘之
静的型付きオブジェクト指向言語 のための 暗黙的に型定義されるレコード
暗黙的に型付けされる構造体の Java言語への導入
プログラミング言語論 第9回 Hoare論理の練習問題 手続きの引数機構 変数の有効範囲
理学部 情報科学科 指導教官 千葉 滋 助教授 学籍番号 03_03686 内河 綾
構文定義記述を用いた 多言語対応コードクローン検出ツールの改善
インラインスクリプトに対するデータフロー 解析を用いた XHTML 文書の構文検証
JDBC データベース論 第12回.
Javaによる Webアプリケーション入門 第7回
ソフトウェア制作論 平成30年10月3日.
プログラミング言語論 第五回 理工学部 情報システム工学科 新田直也.
Java8について 2014/03/07.
アスペクト指向言語のための 独立性の高いパッケージシステム
JDBC J2EE I (データベース論) 第5回 /
多様なプログラミング言語に対応可能な コードクローン検出ツール CCFinderSW
JDBC ソフトウェア特論 第3回.
コンパイラ 2011年10月20日
コーディングパターンの あいまい検索の提案と実装
JavaScriptを含んだHTML文書に対する データフロー解析を用いた構文検証手法の提案
3.1 ifステートメント 3.2 if-elseステートメント 3.3 コードのブロック 11月14日(金) 発表者:藤井丈明
プログラミング言語論 第十一回 理工学部 情報システム工学科 新田直也.
オブジェクト指向言語論 第三回 知能情報学部 新田直也.
統合開発環境によって表現された 言語機構によるコードのモジュール化
同期処理のモジュール化を 可能にする アスペクト指向言語
プログラムの差分記述を 容易に行うための レイヤー機構付きIDEの提案
オープンソースソフトウェアに対する コーディングパターン分析の適用
アルゴリズムとデータ構造1 2009年6月15日
第5回 プログラミングⅡ 第5回
オブジェクト指向言語論 第五回 知能情報学部 新田直也.
状況に応じて適切な 例外処理が行なえる アスペクト指向分散環境実験の 支援ツール
情報処理Ⅱ 2005年10月28日(金).
統合開発環境のための プログラミング言語拡張 フレームワーク
JAVA入門⑥ クラスとインスタンス.
エイリアス関係を考慮した Javaプログラム用静的スライシングツール
オブジェクト指向言語論 第九回 知能情報学部 新田直也.
コンパイラ 2012年10月11日
アルゴリズムとデータ構造 2010年6月17日
プログラミング言語論 第九回 理工学部 情報システム工学科 新田直也.
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
オブジェクト指向言語における セキュリティ解析アルゴリズムの提案と実現
情報処理Ⅱ 小テスト 2005年2月1日(火).
1.2 言語処理の諸観点 (1)言語処理の利用分野
オブジェクト指向言語論 第九回 知能情報学部 新田直也.
Presentation transcript:

内部ドメイン専用言語支援のため の 型に連動した字句・構文ルールの 変更機構 理学部 情報科学科 千葉研究室 07_02363 市川 和央 指導教員 千葉 滋 教授 1

内部ドメイン専用言語(内部 DSL ) ホスト言語の中で作った DSL ホスト言語: 枠組みとなる既存言語 DSL : ある問題の解決に特化した言語 生産性・保守性が向上 繰り返しを排除した可読性の高いコード ホスト言語との連携が容易 Java 中で SQL を利用 2 void printCandidates(int score) { SQLResult candidates = select name from employees where TOEIC_score >= score; System.out.println(candidates.toString()); } void printCandidates(int score) { SQLResult candidates = select name from employees where TOEIC_score >= score; System.out.println(candidates.toString()); } Java の中に SQL の select 文を記述 name や TOEIC_score は Java の変数ではない

表現能力が低い 同じ構文の衝突 難しい 例 1. C/C++ 言語 従来の内部 DSL の実現手法の問題点 1/3 3 #define select select_( #define from, #define where, #define end ); #define select select_( #define from, #define where, #define end ); SQLResult candidates = select “name” from employees where “TOEIC_score >= 600” end SQLResult candidates = select “name” from employees where “TOEIC_score >= 600” end void printNum(int beg, int end) { for(int i = beg; i < end; i++) printf(“%d\n”, i); } void printNum(int beg, int end) { for(int i = beg; i < end; i++) printf(“%d\n”, i); } 条件部分を 文字列で渡している end マクロに書き換えられてしま い 正しくコンパイルできない どのような文を表現 するのかわかりづら い

従来の内部 DSL の実現手法の問題点 2/3 4 例 2. Scheme (define-syntax select (syntax-rules (from where) ((select col from table where cond) (select_ ‘col table cond)))) (define-syntax >= (syntax-rules () ((>= col val) (geq ‘col val)))) (define-syntax select (syntax-rules (from where) ((select col from table where cond) (select_ ‘col table cond)))) (define-syntax >= (syntax-rules () ((>= col val) (geq ‘col val)))) (define candidates (select name from employees where (>= TOEIC_score score))) (define candidates (select name from employees where (>= TOEIC_score score))) 前置記法に変化 括弧も増えている (if (>= (row_count candidates) 10) (draw_lots candidates) candidates) (if (>= (row_count candidates) 10) (draw_lots candidates) candidates) >= マクロが適用されてしまう

従来の内部 DSL の実現手法の問題点 3/3 5 例 3. Scheme( 衝突回避版 ) (define-syntax select (syntax-case x () ((sql-syntax e...) (with-syntax ((expr (datum->syntax (syntax k) ‘(let-syntax ((select (syntax-rules (from where) ((select col from table where cond) (select_ ‘col table cond)))) (>= (syntax-rules () ((>= col val) (geq ‘col val))))),(syntax->datum (syntax (begin e...))))))) (syntax expr))))) (define-syntax select (syntax-case x () ((sql-syntax e...) (with-syntax ((expr (datum->syntax (syntax k) ‘(let-syntax ((select (syntax-rules (from where) ((select col from table where cond) (select_ ‘col table cond)))) (>= (syntax-rules () ((>= col val) (geq ‘col val))))),(syntax->datum (syntax (begin e...))))))) (syntax expr))))) 難しすぎ る! (define candidates (sql-syntax (select name from employees where (>= TOEIC_score score)))) (define candidates (sql-syntax (select name from employees where (>= TOEIC_score score))))

提案: Java に型で制限された ユーザ定義 N 項演算子を導入 Java で強力な内部 DSL を実現可能に DSL の構文を N 項演算子として定義 C++ のオペレータオーバーロードの強化版 優先順位を設定可能に N 項演算子は型情報を持つ SQLResult printCandidates(int score) { SQLResult candidates = select name from employees where TOEIC_score >= score; if(candidates.getRowCount() >= 10) drawLots(candidates); return candidates; } SQLResult printCandidates(int score) { SQLResult candidates = select name from employees where TOEIC_score >= score; if(candidates.getRowCount() >= 10) drawLots(candidates); return candidates; } 6 if(candidates.getRowCount() >= 10) drawLots(candidates); return candidates; select...from...where... 三項演算子とみなす Table 型...>=... 二項演算子とみなす SQLCond 型 Column 型 SQLResult 型

N 項演算子の定義 メソッド定義と似た形式 メソッド名にあたる部分は N 項演算のパターン 7 SQLResult select :col from :table where :cond (readas Column col, Table table, SQLCond cond) : priority = 100 { Connection con =...; Statement stmt = con.createStatement(...); return new SQLResult(stmt.executeQuery(...)); } SQLResult select :col from :table where :cond (readas Column col, Table table, SQLCond cond) : priority = 100 { Connection con =...; Statement stmt = con.createStatement(...); return new SQLResult(stmt.executeQuery(...)); } N 項演算子の オペランド 各オペランドは 引数と対応 キーワード select...from...where... の処理内容 Java で記述

型によるスコーピング SQLResult printCandidates(int score) { SQLResult candidates = select name from employees where TOEIC_score >= score; if(candidates.getRowCount() >= 10) drawLots(candidates); return candidates; } SQLResult printCandidates(int score) { SQLResult candidates = select name from employees where TOEIC_score >= score; if(candidates.getRowCount() >= 10) drawLots(candidates); return candidates; } 期待される型によって N 項演算子を制限 返り値の型が一致しないと利用されない 引数の型もチェック 8 SQLResult 型が期待されるので、 select...from...where... を利用 SQLCond 型が期待されるので、 SQL の...>=... を利用 boolean 型が期待されるので、 通常の意味の...>=... を利用

利用する N 項演算子によってルールを切り替え キーワードの変更 必要に応じた識別子のリテラル化 SQLResult printCandidates(int score) { SQLResult candidates = select name from employees where TOEIC_score >= score; if(candidates.getRowCount() >= 10) drawLots(candidates); return candidates; } SQLResult printCandidates(int score) { SQLResult candidates = select name from employees where TOEIC_score >= score; if(candidates.getRowCount() >= 10) drawLots(candidates); return candidates; } 字句・構文ルールの変更 9 select...from...where... のルールに切り替え SQL の...>=... の ルールに切り替え 通常の意味の...>=... の ルールに切り替え select,from,where はキーワード 第一引数は Column 型として読む Column 型リテラル として読む

従来の手法の問題点を解決 ホスト言語による制限が少ない ホスト言語が構文解析できなくてもよい 型をスコープとして衝突を回避 期待される型によって適切な N 項演算子を選択 ソースコードの改変を意識しなくてよい メタプログラミングを隠蔽 10 実際に本システムで作成した DSL  簡単な select 文( N 項演算子定義部分は 20 行程度)  BNF(N 項演算子定義部分は 30 行程度 )

実装 Java により実装 5500 行程度 コード生成は Javassist を利用 宣言部分と本体部分を別々に解析 本体部分の解析に型や N 項演算子などの情報が必要 字句解析・構文解析・型チェックを連携 型によって N 項演算子を選択し、字句・構文ルールを変更 トップダウン構文解析 式を解析する前にその式の型がわかる必要 11

関連研究 Scala メソッドを単項・二項演算子のように見ることが可能 省略規則の応用によって実現 Smalltalk メッセージを N 項演算のように記述する Registration-Based Language Abstractions [S. Davis, et al, Onward! 2010] エディタによって言語に新たな構文を追加できる 構文木を変換するコードを書かなければならない 字句ルールは変更できない 12

まとめ Java にユーザ定義 N 項演算子を導入することで 内部 DSL を実現可能に 型によって N 項演算子を制限 字句・構文ルールの切り替え 今後の課題 表現力の強化 静的な構文スコープの導入 コンパイル時のオーバーヘッドの測定 13

BNF の規則 具体例 14 目的コード例 ::= “1” | “2” | 略 | “9”; ::= “0” | ; ::= | ; 目的コード例 ::= “1” | “2” | 略 | “9”; ::= “0” | ; ::= | ; 二項演算子 ::= オペレータにあたるも のがない二項演算子 単項演算子 <> operators BNFOperators { BNFExpr :term (String term) :priority = 250 {... } Nonterm (readas String name) :priority = 250 {... } BNFExpr (readas String name) :priority = 250 {... } BNFExpr :s1 :s2 (BNFExpr s1, BNFExpr s2) :priority = 200 {... } BNFExpr :s1 | :s2 (BNFExpr s1, BNFExpr s2) :priority = 150 {... } BNFRule :sym ::= :expr (Nonterm sym, BNFExpr expr) :priority = 100 {... } } operators BNFOperators { BNFExpr :term (String term) :priority = 250 {... } Nonterm (readas String name) :priority = 250 {... } BNFExpr (readas String name) :priority = 250 {... } BNFExpr :s1 :s2 (BNFExpr s1, BNFExpr s2) :priority = 200 {... } BNFExpr :s1 | :s2 (BNFExpr s1, BNFExpr s2) :priority = 150 {... } BNFRule :sym ::= :expr (Nonterm sym, BNFExpr expr) :priority = 100 {... } }

select 文の定義 メソッドの定義と似た形式で定義 15 operators SQLOperators { SQLResult select :col from :table where :cond (readas Column col, Table table, SQLCond cond) : priority = 100 { 普通の Java コード } SQLCond :col >= :val(readas Column col, int val) : priority = 200 { 普通の Java コード } } operators SQLOperators { SQLResult select :col from :table where :cond (readas Column col, Table table, SQLCond cond) : priority = 100 { 普通の Java コード } SQLCond :col >= :val(readas Column col, int val) : priority = 200 { 普通の Java コード } }

select 文の解析 Java の中に次のような select 文を記述できる 16 SQLResult result = select name from employees where TOEIC_score >= 600; SQLResult result = select name from employees where TOEIC_score >= 600; SQLResult 型が必要なの で、 select 文を利用 SQLCond 型が期待 されるので、 >= を利 用 Column 型リテ ラルとして読む int 型引数 Column 型として読 む Table 型の変数