ユーザ定義演算子による 内部 DSL の構成法 市川 和央 千葉 滋 東京工業大学大学院 1. Domain Specific Language (DSL) 用途に応じたミニ言語 select name from register where age < 30 SQL hello : hello.c.

Slides:



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

独習JAVA Chapter 6 6.6 クラスの修飾子 6.7 変数の修飾子 結城 隆. 6.6 クラスの修飾 abstract インスタンス化できないクラス。1つまたは複数のサブクラスで 実装してはじめてインスタンス化できる。 final 継承されたくないことを明示する。これ以上機能拡張 / 変更でき.
内部ドメイン専用言語支援のため の 型に連動した字句・構文ルールの 変更機構 理学部 情報科学科 千葉研究室 07_02363 市川 和央 指導教員 千葉 滋 教授 1.
2.5 プログラムの構成要素 (1)文字セット ① ASCII ( American Standard Code for Interchange ) JIS コードと同じ ② EBCDIC ( Extended Binary Coded Decimal for Information Code ) 1.
プログラミング言語論 第10回(演習) 情報工学科 木村昌臣   篠埜 功.
Web アプリをユーザー毎に カスタマイズ可能にする AOP フレームワーク
情報理工学部 情報システム工学科 ラシキアゼミ 3年 H 井奈波 和也
情報理工学部 情報システム工学科 3年 H 井奈波 和也
密な演算子呼び出しで実現した 内部DSLの前処理による 実行速度改善の試み
背景 我々の研究室で開発しているJavaプログラム解析フレ ームワークでは,解析情報はメモリ上に保持される 問題点
Ex8. Search for Vacuum Problem(2)
Javaのための暗黙的に型定義される構造体
12.3,E,-15, 12.3,E5,+,=, >,<,…,
プログラミング基礎I(再) 山元進.
Myoungkyu Song and Eli Tilevich 発表者: 石尾 隆(大阪大学)
プログラミング言語論 第6回 型 情報工学科 篠埜 功.
第2回:Javaの変数と型の宣言 プログラミングII 2007年10月2日.
プログラミング言語論 第4回 式の構文、式の評価
アルゴリズムとデータ構造 2011年6月13日
言語処理系(5) 金子敬一.
  【事例演習6】  数式インタプリタ      解 説     “インタプリタの基本的な仕組み”.
メソッド名とその周辺の識別子の 相関ルールに基づくメソッド名変更支援手法
ML 演習 第 7 回 新井淳也、中村宇佑、前田俊行 2011/05/31.
補足説明.
細かい粒度でコードの再利用を可能とするメソッド内メソッドのJava言語への導入
JDBC J2EE I 第4回 /
細かい粒度で コードの再利用を可能とする メソッド内メソッドと その効率の良い実装方法の提案
独習JAVA 6.8 コンストラクタの修飾子 6.9 メソッドの修飾子 6.10 ObjectクラスとClassクラス 11月28日(金)
静的型付きオブジェクト指向言語 のための 暗黙的に型定義されるレコード
暗黙的に型付けされる構造体の Java言語への導入
関心事ごとに視点を切り替えて プログラムを編集できる 統合開発環境の提案と実装
理学部 情報科学科 指導教官 千葉 滋 助教授 学籍番号 03_03686 内河 綾
ローカル変数とグローバル変数 ローカル変数  定義された関数内だけで使用できる変数 グローバル変数 プログラム全体で使用できる変数.
オブジェクト指向プログラムにおける エイリアス解析手法の提案と実現
Nakano School of Business 経営情報ビジネス科 【 Java概論(Test5)】
変数のデータフローを考慮した API利用コード例の検索 井上研究室 竹之内 啓太.
JDBC データベース論 第12回.
Javaによる Webアプリケーション入門 第7回
ソフトウェア制作論 平成30年10月3日.
コンパイラ 第13回 上昇型構文解析(1) 38号館4階N-411 内線5459
7.4 intanceof 演算子 7.5~7.9パッケージ 2003/11/28 紺野憲一
Java8について 2014/03/07.
アルゴリズムとデータ構造 2010年6月21日
JDBC J2EE I (データベース論) 第5回 /
pointcut に関して高い記述力を持つ アスペクト指向言語 Josh
コンパイラ 2011年10月20日
B演習(言語処理系演習)第2回 田浦.
JavaScriptを含んだHTML文書に対する データフロー解析を用いた構文検証手法の提案
アルゴリズムとプログラミング (Algorithms and Programming)
プログラミング言語論 第十一回 理工学部 情報システム工学科 新田直也.
オブジェクト指向言語論 第三回 知能情報学部 新田直也.
同期処理のモジュール化を 可能にする アスペクト指向言語
C#プログラミング実習 第3回.
アルゴリズムとデータ構造 2012年6月11日
プログラムの差分記述を 容易に行うための レイヤー機構付きIDEの提案
アルゴリズムとデータ構造1 2009年6月15日
状況に応じて適切な 例外処理が行なえる アスペクト指向分散環境実験の 支援ツール
統合開発環境のための プログラミング言語拡張 フレームワーク
JAVA入門⑥ クラスとインスタンス.
エイリアス関係を考慮した Javaプログラム用静的スライシングツール
オブジェクト指向言語論 第九回 知能情報学部 新田直也.
コンパイラ 2012年10月11日
アルゴリズムとデータ構造 2010年6月17日
Javaとは Javaとはオブジェクト指向言語でJava VM(Java仮想マシン)と呼ばれるプログラム上で動作します。
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
オブジェクト指向言語における セキュリティ解析アルゴリズムの提案と実現
情報処理Ⅱ 小テスト 2005年2月1日(火).
1.2 言語処理の諸観点 (1)言語処理の利用分野
オブジェクト指向言語論 第九回 知能情報学部 新田直也.
計算機プログラミングI 第2回 2002年10月17日(木) 履習登録 複習 ライブラリの利用 (2.6-7) 式・値・代入 (2.6-8)
Presentation transcript:

ユーザ定義演算子による 内部 DSL の構成法 市川 和央 千葉 滋 東京工業大学大学院 1

Domain Specific Language (DSL) 用途に応じたミニ言語 select name from register where age < 30 SQL hello : hello.c cc –c hello.c hello : hello.c cc –c hello.c Make 2

内部 DSL 一つの汎用的な言語の中で DSL を実現 ResultSet rs = select name from register where age < 30; ResultSet rs = select name from register where age < 30; SQL MakeRule hello = “hello.c” cc –c “hello.c”; MakeRule hello = “hello.c” cc –c “hello.c”; Make 3 タブ

HashMap modifiers = { “public” -> 1 “private” -> 2 “protected” -> 4... }; HashMap modifiers = { “public” -> 1 “private” -> 2 “protected” -> 4... }; if ( 0 <= a < 10 ) {... } if ( 0 <= a < 10 ) {... } 比較 Map 4

従来の手法 (ホスト言語に組み込む) ソースコード変換 マクロ 柔軟な記法を用意 シンタックスシュガーを利用 5

柔軟な記法を用意 ☓ DSL の構文がホスト言語に制限される ◯ 複数の DSL やホスト言語と同時に利用できる 6 val rs = sql select “name” from register where (“age” < 30) if (a < 30) {... } val rs = sql select “name” from register where (“age” < 30) if (a < 30) {... } val rs = sql.select(”name”).from(register).where(“age”.<(30)) if(a.<(30)) {... } val rs = sql.select(”name”).from(register).where(“age”.<(30)) if(a.<(30)) {... } 等価 例 : Scala 構文の制限 他の DSL やホスト言語を壊さな い

ソースコード変換 ◯ DSL の構文がホスト言語に殆ど制限されない ☓ 複数の DSL やホスト言語と同時に利用できない 7 ResultSet rs = select name from register where age < 30; if (a < 30) {... } ResultSet rs = select name from register where age < 30; if (a < 30) {... } ResultSet rs = sql_select(name, register, sql_lt(age, 30)); if (sql_lt(a, 30)) {... } ResultSet rs = sql_select(name, register, sql_lt(age, 30)); if (sql_lt(a, 30)) {... } 変換 自由な構文 もとの意味を破壊

提案: ユーザ定義演算子によ る内部 DSL の構成 8

ユーザ定義演算子の利用 DSL の構文を N 項演算子として表現 N 項演算子の形式は自由 ResultSet rs = select name from register where age < 30; ResultSet rs = select name from register where age < 30; 三項演算子 select from where 二項演算子 < 9

期待される型により演算子を制限 返り値の型が期待される型である場合のみ有効 に オペランドも再帰的に制限される ResultSet rs = select name from register where age < 30; ResultSet rs = select name from register where age < 30; 10

期待される型により演算子を制限 返り値の型が期待される型である場合のみ有効 に オペランドも再帰的に制限される ResultSet rs = select name from register where age < 30; ResultSet rs = select name from register where age < 30; ResultSet 型が期待されるので、 select...from...where... が有効 に 11

期待される型により演算子を制限 返り値の型が期待される型である場合のみ有効 に オペランドも再帰的に制限される ResultSet rs = select name from register where age < 30; ResultSet rs = select name from register where age < 30; ResultSet 型が期待されるので、 select...from...where... が有効 に 条件節が期待されるので、 専用の < 演算子が有効に 12

演算子によって文法を切り替える 利用される演算子に応じて解析ルールを変更 13 ResultSet rs = select name from register where age < 30; ResultSet rs = select name from register where age < 30; select...from...where... を利用するので、 select, from, where はキーワードで、 name はカラム 名 条件節の < 演算子を利用するので、 < はキーワードで、 age はカラム 名

従来の手法の問題点を解決 ◯ DSL の構文がホスト言語に殆ど制限されない  演算子によって文法が切り替わる ◯ 複数の DSL を組み合わせて利用できる  期待される型により有効な演算子が制限される 14

制限 型推論との相性が最悪 クラス定義等の式より大きいものは表現できない 左辺値等の期待される型がない所では利用できな い 動的型付け言語では不可能 15

LasticJ Java のサブセットに前述のアイデアを導入 ジェネリクス・インターフェース等はなし コンパイラは Java により実装 名前は変わるかも 16

Select 文の作り方 17

三項演算子 select from where の定義 メソッド定義と似た形式 処理内容はホスト言語で記述 18 ResultSet “select” col “from” table “where” cond (readas SQLColumn col, SQLTable table, SQLCond cond) : priority = 200 { Connection conn =...; Statement stmt = conn.prepareStatement(...); return stmt.executeQuery(); } ResultSet “select” col “from” table “where” cond (readas SQLColumn col, SQLTable table, SQLCond cond) : priority = 200 { Connection conn =...; Statement stmt = conn.prepareStatement(...); return stmt.executeQuery(); } 返り値の型 処理内容 キーワー ド オペランドの 型 オペラン ド

演算子モジュール 同一の機能に関する演算子を集めたもの 演算子定義はここに記述 19 operators SQLOperators { ResultSet “select” col “from” table “where” cond (readas SQLColumn col, SQLTable table, SQLCond cond) : priority = 200 {... } SQLCond col “<“ val (readas SQLColumn col, int val) : priority = 100 {... }... } operators SQLOperators { ResultSet “select” col “from” table “where” cond (readas SQLColumn col, SQLTable table, SQLCond cond) : priority = 200 {... } SQLCond col “<“ val (readas SQLColumn col, int val) : priority = 100 {... }... } 三項演算子 select from where 二項演算子 <

演算子の利用 using 節により利用する演算子モジュールを指定 20 using lasticj.test.sql.SQLOperators; class Test { public void run() { SQLTable register =...; ResultSet rs = select name from register where age < 30;... } using lasticj.test.sql.SQLOperators; class Test { public void run() { SQLTable register =...; ResultSet rs = select name from register where age < 30;... } SQLOperators を利用 SQLOperators の演算子を利用して解釈

ResultSet “select” col “from”... (readas SQLColumn col,...)... ResultSet “select” col “from”... (String col,...)... readas 修飾子 オペランドの位置の単語をリテラルとして読む 21 ResultSet rs = select “name” from register where “age” < 30; ResultSet rs = select “name” from register where “age” < 30; ResultSet rs = select name from register where age < 30; ResultSet rs = select name from register where age < 30; SQLColumn 型の リテラルとして解 釈 このようなダブル クォートは書きたくな い

実装について 22

コンパイラ全体 Java により実装 ( 約 8000 行 ) 宣言部分と本体部分を分けて解析 コード生成には javassist を利用 23

本体部分の構文解析法 Packrat parsing のアルゴリズムを利用 字句解析器・構文解析器・型チェッカーが一体 化 式の解析は次のようにして行う 1. 期待される型を返す演算子を優先度順に試す 2. 最初に成功したものを結果として返す 3. 全て失敗した場合、通常の Java のルールで解析する 24

関連研究 SugarJ [ S. Erdweg ら ’11 ] ユーザがシンタックスシュガーをライブラリとして定 義 文法が衝突すると一方が破壊される Template Haskell [ T. Sheard ら ‘02 ] 型安全なコンパイル時メタプログラミング ユーザが直接構文木を操作しなければならない Scala メソッド呼び出しを単項・二項演算のように記述でき る 実現可能な内部 DSL の文法に制約がある 25

まとめ ユーザ定義演算子による内部 DSL の構成法を提 案 このアイデアを導入した言語 LasticJ を作成 26 今後の課題 記述力の強化 様々な内部 DSL を実際に構築する

27 operators SQLOperators { ResultSet “select” col “from” table “where” cond (readas SQLColumn col, SQLTable table, SQLCond cond) : priority = 200 {... } SQLCond col “<“ val (readas SQLColumn col, int val) : priority = 100 {... } } operators SQLOperators { ResultSet “select” col “from” table “where” cond (readas SQLColumn col, SQLTable table, SQLCond cond) : priority = 200 {... } SQLCond col “<“ val (readas SQLColumn col, int val) : priority = 100 {... } } ResultSet rs = select name from register where age < 30; ResultSet rs = select name from register where age < 30;

28 MakeRule hello = “hello.c” cc –c “hello.c”; MakeRule hello = “hello.c” cc –c “hello.c”; operators MakeOperators { MakeRule file “\t“ script (String file, Script script) : priority = 100 {... } Script command option file (readas Command command, Option option, String file) : priority = 100 {... } Option “-” op (readas String op) : priority = 100 {... } } operators MakeOperators { MakeRule file “\t“ script (String file, Script script) : priority = 100 {... } Script command option file (readas Command command, Option option, String file) : priority = 100 {... } Option “-” op (readas String op) : priority = 100 {... } }

29 operators BoolOperators { boolean a “<=“ b “<“ c (int a, int b, int c) : priority = 1000 {... } } operators BoolOperators { boolean a “<=“ b “<“ c (int a, int b, int c) : priority = 1000 {... } } if ( 0 <= a < 10 ) {... } if ( 0 <= a < 10 ) {... }

30 注) 現在の実装ではジェネリクス及び 0 回以上の繰り返しを示す... には 対応していないため、実際には余分なクラスと演算子をいくつか作る 必要がある。 HashMap modifiers = { “public” -> 1 “private” -> 2 “protected” -> 4... }; HashMap modifiers = { “public” -> 1 “private” -> 2 “protected” -> 4... }; operators MapOperators { Map “{“ entries “}” (MapEntry... entries) : priority = 100 {... } MapEntry key “->” val (K key, V val) : priority = 100 {... } } operators MapOperators { Map “{“ entries “}” (MapEntry... entries) : priority = 100 {... } MapEntry key “->” val (K key, V val) : priority = 100 {... } }

演算子優先順位 演算子ごとに優先度を設定 優先度が同じ場合は using 節の順序により決定 31 大 後 小 前 優先度 using 順序 AST

さらなる利点 IDE との相性が非常に良い ホスト言語を単純化できる 32

readas 修飾子 N 項演算子のオペランドに対して指定 単語を与えられた型のリテラルとして読む事を 示す 一旦文字列として読み、コンストラクタで変換 33 ResultSet “select” col “from” table “where” cond (readas SQLColumn col, SQLTable table, SQLCond cond) : priority = 200 {... } ResultSet rs = select name from register where age < 30; ResultSet rs = select name from register where age < 30; readas SQLColumn SQLColumn 型 リテラルとして解 釈