(邦訳:合成可能かつ静的検査可能なドメイン専用言語のためのプラットフォーム)
市川 和央 ファイブ(株) エンジニア |
[背景]ドメイン専用言語(DSL)と内部DSL
[問題]DSLの文法の自由度,静的検査可能性,合成可能性
[貢献]言語のさまざまな機能を自由に組み合わせて使える開発環境
[問題]DSLの文法の自由度,静的検査可能性,合成可能性
[貢献]言語のさまざまな機能を自由に組み合わせて使える開発環境
本研究はドメイン専用言語(DSL)の開発基盤となるシステムに関する研究である.同様の研究はいくつか存在するが,本研究のユニークな点は
① DSLに利用できる文法の制限が小さく,
② DSLの文法検査・名前解決を静的に行うことができ,
③ その上で,開発したDSL同士の合成可能性を損なわない
という点である.
DSL同士の合成可能性とは,複数のまったく別々に作られたDSLを組み合わせて一つのDSLのようにして扱うことができるという性質を指す.我々が目指しているのは,プログラミング言語のさまざまな機能をライブラリのように自由に組み合わせて使うことができる開発環境である.本研究はその一歩として,さまざまな言語機構を単機能のDSLとして実装でき,それらを合成できるシステムを提案している.
DSLの実装方針は,大きく分けると外部DSLと内部DSLという2つが存在する.外部DSLはDSLを独立した一つの言語として実装するというアプローチである.この方針は,DSL独自の構文解析器や名前解決器を実装することになるため,文法の自由度が高く,DSLの文法検査・名前解決を静的に行うように実装することができる.しかし,実装した外部DSL同士は独立した言語であるため,これらを合成して利用することはできない.対して内部DSLは,DSLを汎用言語(ホスト言語)のライブラリとして実装するというアプローチである.実装したDSLはライブラリにすぎないので,複数のDSLをimportすればそれらを組み合わせて利用することができる.内部DSLの欠点は,文法の自由度が低いことである.内部DSLはあくまでライブラリなので,ホスト言語で表現できる範囲の文法しか扱うことができない.静的な名前解決もホスト言語側の機能を使うほかないため,言語設計が制限される.
そこで本研究では,ホスト言語の静的な型を利用して構文拡張および名前解決の拡張ができるシステムを提案している.ホスト言語の静的な型を構文規則の非終端記号とみなし,さらに型引数を利用することで文脈依存性のある文法を表現可能にする.変数名のような名前は文脈依存文法により表現できるため,こうすることで静的な文法検査・名前解決を表現できる.本研究では,このようなシステムを実現するための型検査器と連動した構文解析器の実装手法を示し,それを実装した言語ProteaJおよびProteaJ2を紹介している.
ProteaJおよび ProteaJ2では,提案機能を強力なユーザ定義演算子として実装している.ユーザは好きな文法を持つ関数を演算子として定義することができる.定義した演算子の文法は返り値の型が期待されるような場所でのみ利用できる.また,この演算子のオペランド部分では対応する引数の型を返す演算子の文法が利用可能となる.これが静的な型を構文規則の非終端記号として扱うということである.ProteaJ2ではこれに加え,構文木を表す型引数を持つことができる.型引数で与えられた構文木は構文規則中で利用することができ,その部分の解析結果が同一構文木でなければならないことを示す.これを利用して変数名の一致等を検証することができるため,DSL独自の名前解決を実装できる.
① DSLに利用できる文法の制限が小さく,
② DSLの文法検査・名前解決を静的に行うことができ,
③ その上で,開発したDSL同士の合成可能性を損なわない
という点である.
DSL同士の合成可能性とは,複数のまったく別々に作られたDSLを組み合わせて一つのDSLのようにして扱うことができるという性質を指す.我々が目指しているのは,プログラミング言語のさまざまな機能をライブラリのように自由に組み合わせて使うことができる開発環境である.本研究はその一歩として,さまざまな言語機構を単機能のDSLとして実装でき,それらを合成できるシステムを提案している.
DSLの実装方針は,大きく分けると外部DSLと内部DSLという2つが存在する.外部DSLはDSLを独立した一つの言語として実装するというアプローチである.この方針は,DSL独自の構文解析器や名前解決器を実装することになるため,文法の自由度が高く,DSLの文法検査・名前解決を静的に行うように実装することができる.しかし,実装した外部DSL同士は独立した言語であるため,これらを合成して利用することはできない.対して内部DSLは,DSLを汎用言語(ホスト言語)のライブラリとして実装するというアプローチである.実装したDSLはライブラリにすぎないので,複数のDSLをimportすればそれらを組み合わせて利用することができる.内部DSLの欠点は,文法の自由度が低いことである.内部DSLはあくまでライブラリなので,ホスト言語で表現できる範囲の文法しか扱うことができない.静的な名前解決もホスト言語側の機能を使うほかないため,言語設計が制限される.
そこで本研究では,ホスト言語の静的な型を利用して構文拡張および名前解決の拡張ができるシステムを提案している.ホスト言語の静的な型を構文規則の非終端記号とみなし,さらに型引数を利用することで文脈依存性のある文法を表現可能にする.変数名のような名前は文脈依存文法により表現できるため,こうすることで静的な文法検査・名前解決を表現できる.本研究では,このようなシステムを実現するための型検査器と連動した構文解析器の実装手法を示し,それを実装した言語ProteaJおよびProteaJ2を紹介している.
ProteaJおよび ProteaJ2では,提案機能を強力なユーザ定義演算子として実装している.ユーザは好きな文法を持つ関数を演算子として定義することができる.定義した演算子の文法は返り値の型が期待されるような場所でのみ利用できる.また,この演算子のオペランド部分では対応する引数の型を返す演算子の文法が利用可能となる.これが静的な型を構文規則の非終端記号として扱うということである.ProteaJ2ではこれに加え,構文木を表す型引数を持つことができる.型引数で与えられた構文木は構文規則中で利用することができ,その部分の解析結果が同一構文木でなければならないことを示す.これを利用して変数名の一致等を検証することができるため,DSL独自の名前解決を実装できる.

(2018年6月25日受付)