Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Upcoming SlideShare
テンプレート・エンジンVelocity
Next
Download to read offline and view in fullscreen.

0

Share

Download to read offline

オレオレ言語実装に役立つプル型ASTウォーカーAPI

Download to read offline

第14回福岡市西区プログラム勉強会資料(2016/07/03)
Lore言語実装の副産物として汎用ASTライブラリを作成したので紹介した。
(1) シンプルな単一種類ノードのASTに型チェック付きで様々な型のアトリビュートを格納するAST実装
(2) ASTを辿る過程をイベント・ストリームに変換してアクセスすることでイベント駆動でないプル型のアクセスを可能にするASTウォーカーの実装
(先行事例はちゃんと調べてないので「あるある」実装かも。)

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all
  • Be the first to like this

オレオレ言語実装に役立つプル型ASTウォーカーAPI

  1. 1. オレオレ言語実装に役立つ プル型ASTウォーカーAPI 神戸隆行(椎路ちひろ)Twitter: @ChihiroShiiji / FB: takayuki.kando 2016/07/03(第14回福岡市西区プログラム勉強会資料) XGMTK & Lore
  2. 2. 自己紹介  神戸 隆行(かんど たかゆき)、PN. 椎路ちひろ(しいじ ちひろ) Twitter: @ChihiroShiiji / FB: takayuki.kando  出身は名古屋、趣味イラストとコスプレ  九大の社会人博士課程で博士を取ろうとしながら研究開発に従事する失業者  専門は流転中:  数値解析(のプログラミング・インターフェースの改良、修論@名大) →数式処理(のプログラミング・インターフェースの改良@某F研) →プログラム最適化(博士課程一回目の失敗@東工大) (2005年に仕事を紹介され福岡へ来た) →コンパイラ開発(Redefis、動的再構成可能プロセッサ向けコンパイラ) →SW/HW開発環境(IDE上からクラウド上の開発ツールを利用できるミドルウェア PTaaSの開発) http://www.qualiarc.com/?post_type=seihin&p=202  使用プログラミング言語:  最初はFORTRAN、大学以降はC++とC、今は主にJava、他は必要に応じてボチボチ  本日は趣味で開発しているLore言語の実装の副産物  幾つかのソースとサンプルをGitHub[ https://github.com/TakayukiKando/LoreAST ]に置いてま す 2016/07/032 第14回福岡市西区プログラム勉強会
  3. 3. 本日の内容「プル型ASTウォーカーAPI 」 2016/07/03第14回福岡市西区プログラム勉強会3  LoreAST  TRPGルールシナリオ記述言語Loreの実装に使うつもりで作 成しているASTライブラリ  オンライン/オフライン・セッション支援ツールXGMTKで利用する  XGMTKはルールやシナリオを実行可能な形で記述することでルール主 導のセッション支援ツール  本日は主にそのASTにアクセスするAPIの設計について  構文解析結果を保存するデータ構造としてツリーは良いけれど、意 外とアクセスが面倒くさい  先行事例を調べていないのでもしかしたら「あるある」事 例かも  ……まぁ小ネタですし
  4. 4. 具象構文木(CST…Concrete Syntax Tree) と 抽象構文木(AST…Abstract Syntax Tree) 2016/07/03第14回福岡市西区プログラム勉強会4 例(代入文): d=(a+b)*c; 代入文 =d 式 * c項 + ba 項 )( CST: 構文規則の適用を記録し、ソースの記号列の解 析結果を忠実に記録したデータ構造 非終端記号 終端記号 代入文 id: d 式: * id: c式: + id: bid: a AST: 構文が表現していたプログラムの構造を抽象的 に表現したデータ構造 構文解析のデ バッグに便利 プログラムの解 析に便利
  5. 5. ASTの実装 - Node.java 2016/07/03第14回福岡市西区プログラム勉強会5 public final class Node { private final Map<Attribute<?>, Object> attrs; /* アトリビュート(後述) */ private final List<Node> children; /* 子ノード */ /* コンストラクタ */ public Node(List<Node> children){/* 省略 */} public Node(Node...children){/* 省略 */} /* アトリビュート(後述)の取得と設定、存在の確認 */ public final <T> void setAttribute(Attribute<T> attribute, T value){/* 省略 */} public final <T> T getAttribute(Attribute<T> attribute){/* 省略 */} public Map<Attribute<?>, Object> attributes() {/* 省略 */} public final <T> boolean hasAttribute(Attribute<T> attribute){/* 省略 */} /* 子ノードの追加と取得 */ public final void addChildren(Node...children){/* 省略 */} public final void addChildren(List<Node> children) {/* 省略 */} public List<Node> children(){/* 省略 */} /* 等値演算とハッシュコード(ツリー比較、テスト用) */ @Override public boolean equals(Object obj){/* 省略 */} @Override public int hashCode() {/* 省略 */} /* ビジター受け入れメソッド(後述) */ public final void startVisit(Visitor visitor) {/* 省略 */} }
  6. 6. 追加可能で静的型検査可能なアトリビュート・ マップ 2016/07/03第14回福岡市西区プログラム勉強会6 public interface Attribute<T> { } • アトリビュートのキーとなるenum型群のためのインターフェー ス • 型パラメータTがミソ public class Attributes{ public enum LocationAttr implements Attribute<Location>{ LOCATION; } public static final LocationAttr LOCATION = LocationAttr.LOCATION; public enum StringAttr implements Attribute<String>{ SYMBOL; } public static final StringAttr SYMBOL = StringAttr.SYMBOL; } public final <T> T getAttribute(Attribute<T> attribute){/* 省略 */} • NodeのgetAttributeメソッド…キーの型パラメータの型と同じ型が返る • enumにしてるのはキーをお手 軽にシングルトンにするため • Locationはノードの由来となっ たコードの位置を示すデータ構 造(エラーメッセージ等に利用) • ここでは記号文字列を格納する SYMBOLとソースコード上の位 置を示すLOCATIONだけだが、 Attribute<T>を継承すれば追加 できる。
  7. 7. ツリーを辿る(1)…ビジタ(Visitor) 2016/07/03第14回福岡市西区プログラム勉強会7  アルゴリズムによって定まる順番 でツリーのノードを訪問するビジ ター  深さ優先探索や幅優先探索など  ツリーを辿る定番デザイン・パター ン  長所: enterとleaveメソッドの呼び 出しによりサブツリーの開始と終 了を認識できる  短所: コールバックによるイベント 駆動的なコードになり構造をツリー の意識した記述がしにくい  ASTではサブツリーのパターンに よって処理を分けて記述するような ことがしたい  ノードの種類を増やしてビジタのメ ソッドを増やして実装をFatにすれば ある程度できるが、メンテが面倒に  短所: 継承が必須であり、用途毎 にビジタ・クラスが増える 代入文 id: d 式: * id: c式: + id: bid: a enter #0 leave #6 enter #1 leave #0 enter #2 leave #5 enter #3 leave #3 enter #4 leave #1 enter #5 leave #2 enter #6 leave #4 順番の例、深さ優先探索の場合 • vをビジタ・オブジェクトとして以下の様に動作: • ノードに初回訪問時にv.enter()が呼ばれる • ノードへの最後の訪問時(leafノードでは v.enter()の直後)にv.leave()が呼ばれる
  8. 8. ツリーを辿る(2)…イテレータ(Iterator) 2016/07/03第14回福岡市西区プログラム勉強会8  アルゴリズムによって定まる順番で ツリーのノードを訪問することをイテ レータ化  深さ優先探索や幅優先探索など  ツリーに限らずグラフ探索全般で利用で きる簡単で優れた抽象化  長所: 制御をプログラム主導で行え るのでアルゴリズムが記述し易い  短所: AST処理で良くある、サブツ リーを辿り終わった後で何か処理を するようなコードが書きにくい  サブツリーのルートノードを再訪する アルゴリズムにしたとしても初回と再 訪が区別できない  区別する述語は追加できるがあまり使い やすくはない 代入文 id: d 式: * id: c式: + id: bid: a #0 #1 #2 #3 #6 #4 #5 順番の例、深さ優先探索の場合 • itをイテレータ・オブジェクトとして以 下の様に動作: • it.next()すると次のノードが取れ る • it.hasNext()が真を返している間 は次がある
  9. 9. ツリーを辿る(3)…プル型ウォーカ(Pull Walker) 2016/07/03第14回福岡市西区プログラム勉強会9  アルゴリズムによって定まる 順番でツリーのノードを訪問 することをイベント・ストリー ムに変換する  深さ優先探索や幅優先探索 など  長所: enterとleaveイベント によりサブツリーの開始と 終了を認識できる  長所: イテレータ同様にプロ グラム主導で行えるのでア ルゴリズムが記述し易い  ASTではサブツリーのパ ターンによって処理を分けて 記述するようなことがしたい 代入文 id: d 式: * id: c式: + id: bid: a enter #0 leave #6 enter #1 leave #0 enter #2 leave #5 enter #3 leave #3 enter #4 leave #1 enter #5 leave #2 enter #6 leave #4 順番の例、深さ優先探索の場合 • sをイベント・ストリーム・オブジェクトとして以下の様に動 作: • s.next()で次のイベントへ遷移 • getCurrentEvent()でイベント取得 • イベントはSTART(初期状態)、ENTER(ノード訪問)、 LEAVE(サブツリー終了)、FINISH(ツリー全体の終 了)の4タイプで、現在のノードが格納されている
  10. 10. アイディア元: XML Pull Parser  http://www.xmlpull.org/  実装例  kXML  Web: http://www.kxml.org/  SourceForge(JARファイル): https://sourceforge.net/projects/kxml/  MXP1(Smackが使っているが、ダウンロードURLがリンク切 れ)  http://www.extreme.indiana.edu/xgws/xsoap/xpp/mxp1/  XMLのパース結果をイベントストリームに変換  SAXパーサ(イベント駆動)とDOMツリーの間を取ったXML パーサインターフェース 2016/07/0310 第14回福岡市西区プログラム勉強会
  11. 11. イベント・ストリーム Visitorスレッド プル型ツリーウォーカの構造 2016/07/03第14回福岡市西区プログラム勉強会11 代入文 id: d 式: * id: c式: + id: bid: a enter #0 leave #6 enter #1 leave #0 enter #2 leave #5 enter #3 leave #3 enter #4 leave #1 enter #5 leave #2 enter #6 leave #4 ビジタ 固定長 ブロッキング・ キュー 利用側 スレッド ひたすら辿っ てイベントを作 成して投入 利用側の好きなタ イミングで順にイベ ントを取り出す • イベント駆動の挙動を変換するのに使っているだけなのでキューの容量は0でも良 い • 利用側の処理速度によってはツリーの全ノード分のイベントがキューに溜まる可能 性があるので可変長は止めておいた方が良い
  12. 12. ASTStream.java (1) - フィールド 2016/07/03第14回福岡市西区プログラム勉強会12 public class ASTStream { /* プライベート定数省略 */ /* フィールド */ private ASTEvent current; // 現在のイベント private final BlockingQueue<ASTEvent> queue; // イベント・キュー private final Node root; // 現在のノード private final Visitor visitor; // ツリーを辿るビジター private final ExecutorService executor; // スレッド実行サービス private boolean finished; // 終了状態を示すフラグ /* 内部クラスとプライベートメソッド省略 */
  13. 13. ASTStream.java (2) - メソッド 2016/07/03第14回福岡市西区プログラム勉強会13 /* コンストラクタ */ public ASTStream(Node root, int queueLength) {/* 省略 */} public ASTStream(Node root){/* 省略 */} /* ストリームの開始 */ public Future<Boolean> start(){/* 省略 */} /* 現在のイベント */ public ASTEvent getEvent(){/* 省略 */} /* 現在のイベントのノード */ public Node getNode(){/* 省略 */} /* 次のイベントへ遷移 */ public void next() throws IllegalStateException {/* 省略 */} /* 判定と検証(後述) */ public boolean is(Predicate<ASTEvent> predicate) {/* 省略 */} public void require(Predicate<ASTEvent> predicate) throws ASTStreamInvalidException {/* 省略 */} /* スキップ(後述) */ public void skipTo(Predicate<ASTEvent> predicate) {/* 省略 */} }
  14. 14. イベントの判定と検証 2016/07/03第14回福岡市西区プログラム勉強会14  is(predicate)  現在のイベントに応じて場合分けするための述語  require(predicate)  現在のイベントが想定通りかどうか検証し、不正な場合は例 外を投げる  predicateはPredicate<ASTEvent>型の1引数関数オブ ジェクト  EventMatcherに良く使う述語を返すメソッドを用意してある
  15. 15. EventMatcher 2016/07/03第14回福岡市西区プログラム勉強会15  match(type)  イベント型がtypeであることを判定する述語を返す  主に他の述語との組み合わせ用だがSTARTとFINISHの判定にも使う  match(attribute, value)  attributeで指定されるアトリビュートがvalueに等しいことを判定する述語を返す  主に他の述語との組み合わせ用  match(type, attribute, value)  イベント型がtypeでattributeで指定されるアトリビュートがvalueに等しいことを 判定する述語を返す  enter(attribute, value)  イベント型がENTERでattributeで指定されるアトリビュートがvalueに等しいことを判定す る述語を返す  same(node)  指定されたノード同じノードのイベントであることを判定する述語を返す  主に他の述語との組み合わせ用  leave(node)  指定されたノードのLEAVEイベントであることを判定する述語を返す
  16. 16. イベントのスキップ 2016/07/03第14回福岡市西区プログラム勉強会16  ASTの全てのノードを処理しない応用も多いので処理し ないノードをスキップできると便利  skipTo(predicate)  条件に合うイベントまでスキップ  predicateはis()及びrequire()と同じ  実装はis(predicate)が真になるまでnext()が繰り返し呼ばれ るだけ  計測していないが、マルチプロセッサ環境ではイベントキューの容量 を0より程良く大きくしておくと、スキップしない処理の間にキューにイ ベントが貯まってskipTo()が早くなるかも?
  17. 17. 今後 2016/07/03第14回福岡市西区プログラム勉強会17  特定の条件とその条件に合致した場合の処理をまとめ て書く「パターンマッチ」の実装  現状: if文にis()とskipTo()との組み合わせでは処理中のサブ ツリーにパターンがあった場合(入れ子)の処理ができない  ASTの書き換え処理の実装  現状: ASTを辿ることはできるが書き換えをサポートしていな い
  18. 18. まとめ プル型ASTウォーカーAPI 2016/07/03第14回福岡市西区プログラム勉強会18  言語処理系の基本データ構造であるAST(Abstract Syntax Tree)の復習  Lore言語実装の副産物として汎用ASTライブラリを作成 したので紹介した  シンプルな単一種類ノードのASTに型チェック付きで様々な型 のアトリビュートを格納するAST実装  総称型キーを利用した汎用getter  enumによる簡易なシングルトン・オブジェクトをキーに利用  ASTを辿る過程をイベント・ストリームに変換してアクセスする ことでイベント駆動でないプル型のアクセスを可能にするAST ウォーカーの実装  マルチスレッド&ブロッキングキューの応用でイベント駆動から変換  関数型を利用したシンプルな場合分け、検証、スキップ機能

第14回福岡市西区プログラム勉強会資料(2016/07/03) Lore言語実装の副産物として汎用ASTライブラリを作成したので紹介した。 (1) シンプルな単一種類ノードのASTに型チェック付きで様々な型のアトリビュートを格納するAST実装 (2) ASTを辿る過程をイベント・ストリームに変換してアクセスすることでイベント駆動でないプル型のアクセスを可能にするASTウォーカーの実装 (先行事例はちゃんと調べてないので「あるある」実装かも。)

Views

Total views

1,897

On Slideshare

0

From embeds

0

Number of embeds

19

Actions

Downloads

6

Shares

0

Comments

0

Likes

0

×