狠狠撸

狠狠撸Share a Scribd company logo
オレオレ言語実装に役立つ
プル型ASTウォーカーAPI
神戸隆行(椎路ちひろ)Twitter: @ChihiroShiiji / FB: takayuki.kando
2016/07/03(第14回福岡市西区プログラム勉強会資料)
XGMTK & Lore
自己紹介
? 神戸 隆行(かんど たかゆき)、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回福岡市西区プログラム勉強会
本日の内容「プル型ASTウォーカーAPI 」
2016/07/03第14回福岡市西区プログラム勉強会3
? LoreAST
? TRPGルールシナリオ記述言語Loreの実装に使うつもりで作
成しているASTライブラリ
? オンライン/オフライン?セッション支援ツールXGMTKで利用する
? XGMTKはルールやシナリオを実行可能な形で記述することでルール主
導のセッション支援ツール
? 本日は主にそのASTにアクセスするAPIの設計について
? 構文解析結果を保存するデータ構造としてツリーは良いけれど、意
外とアクセスが面倒くさい
? 先行事例を調べていないのでもしかしたら「あるある」事
例かも
? ……まぁ小ネタですし
具象構文木(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:
構文が表現していたプログラムの構造を抽象的
に表現したデータ構造
?構文解析のデ
バッグに便利
?プログラムの解
析に便利
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) {/* 省略 */}
}
追加可能で静的型検査可能なアトリビュート?
マップ
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>を継承すれば追加
できる。
ツリーを辿る(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()が呼ばれる
ツリーを辿る(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()が真を返している間
は次がある
ツリーを辿る(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タイプで、現在のノードが格納されている
アイディア元: 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回福岡市西区プログラム勉強会
イベント?ストリーム
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でも良
い
? 利用側の処理速度によってはツリーの全ノード分のイベントがキューに溜まる可能
性があるので可変長は止めておいた方が良い
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; // 終了状態を示すフラグ
/* 内部クラスとプライベートメソッド省略 */
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) {/* 省略 */}
}
イベントの判定と検証
2016/07/03第14回福岡市西区プログラム勉強会14
? is(predicate)
? 現在のイベントに応じて場合分けするための述語
? require(predicate)
? 現在のイベントが想定通りかどうか検証し、不正な場合は例
外を投げる
? predicateはPredicate<ASTEvent>型の1引数関数オブ
ジェクト
? EventMatcherに良く使う述語を返すメソッドを用意してある
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イベントであることを判定する述語を返す
イベントのスキップ
2016/07/03第14回福岡市西区プログラム勉強会16
? ASTの全てのノードを処理しない応用も多いので処理し
ないノードをスキップできると便利
? skipTo(predicate)
? 条件に合うイベントまでスキップ
? predicateはis()及びrequire()と同じ
? 実装はis(predicate)が真になるまでnext()が繰り返し呼ばれ
るだけ
? 計測していないが、マルチプロセッサ環境ではイベントキューの容量
を0より程良く大きくしておくと、スキップしない処理の間にキューにイ
ベントが貯まってskipTo()が早くなるかも?
今後
2016/07/03第14回福岡市西区プログラム勉強会17
? 特定の条件とその条件に合致した場合の処理をまとめ
て書く「パターンマッチ」の実装
? 現状: if文にis()とskipTo()との組み合わせでは処理中のサブ
ツリーにパターンがあった場合(入れ子)の処理ができない
? ASTの書き換え処理の実装
? 現状: ASTを辿ることはできるが書き換えをサポートしていな
い
まとめ
プル型ASTウォーカーAPI
2016/07/03第14回福岡市西区プログラム勉強会18
? 言語処理系の基本データ構造であるAST(Abstract
Syntax Tree)の復習
? Lore言語実装の副産物として汎用ASTライブラリを作成
したので紹介した
? シンプルな単一種類ノードのASTに型チェック付きで様々な型
のアトリビュートを格納するAST実装
? 総称型キーを利用した汎用getter
? enumによる簡易なシングルトン?オブジェクトをキーに利用
? ASTを辿る過程をイベント?ストリームに変換してアクセスする
ことでイベント駆動でないプル型のアクセスを可能にするAST
ウォーカーの実装
? マルチスレッド&ブロッキングキューの応用でイベント駆動から変換
? 関数型を利用したシンプルな場合分け、検証、スキップ機能
Ad

Recommended

颁贰顿贰颁2015「加算合成コストが0になる!?すぐに使える笔-惭础笔ブレンドテクニック」発表スライド
颁贰顿贰颁2015「加算合成コストが0になる!?すぐに使える笔-惭础笔ブレンドテクニック」発表スライド
Toshiyasu Miyabe
?
[DL輪読会] マルチエージェント強化学習と心の理論
[DL輪読会] マルチエージェント強化学習と心の理論
Deep Learning JP
?
滨蹿文から机械学习への道
滨蹿文から机械学习への道
nishio
?
リーンなコードを书こう:実践的なオブジェクト指向设计
リーンなコードを书こう:実践的なオブジェクト指向设计
増田 亨
?
C++ マルチスレッド 入門
C++ マルチスレッド 入門
京大 マイコンクラブ
?
【鲍苍颈迟测道场】物理シミュレーション完全マスター
【鲍苍颈迟测道场】物理シミュレーション完全マスター
Unity Technologies Japan K.K.
?
Word Tour: One-dimensional Word Embeddings via the Traveling Salesman Problem...
Word Tour: One-dimensional Word Embeddings via the Traveling Salesman Problem...
joisino
?
笔测迟丑辞苍による黒魔术入门
笔测迟丑辞苍による黒魔术入门
大樹 小倉
?
形状解析のための楕円フーリエ変换
形状解析のための楕円フーリエ変换
Tsukasa Fukunaga
?
浮动小数点(滨贰贰贰754)を圧缩したい@诲蝉颈谤苍濒辫#4
浮动小数点(滨贰贰贰754)を圧缩したい@诲蝉颈谤苍濒辫#4
Takeshi Yamamuro
?
[DL輪読会]Deep Neural Networks as Gaussian Processes
[DL輪読会]Deep Neural Networks as Gaussian Processes
Deep Learning JP
?
圏论のモナドと贬补蝉办别濒濒のモナド
圏论のモナドと贬补蝉办别濒濒のモナド
Yoshihiro Mizoguchi
?
プログラムの処方笺~健康なコードと病んだコード
プログラムの処方笺~健康なコードと病んだコード
Shigenori Sagawa
?
データに内在する构造をみるための埋め込み手法
データに内在する构造をみるための埋め込み手法
Tatsuya Shirakawa
?
ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14
Ryo Suzuki
?
さるでも分かりたい9诲辞蹿で作るクォータニオン姿势
さるでも分かりたい9诲辞蹿で作るクォータニオン姿势
ytanno
?
第126回 ロボット工学セミナー 三次元点群と深層学習
第126回 ロボット工学セミナー 三次元点群と深層学習
Naoya Chiba
?
オブジェクト指向できていますか?
オブジェクト指向できていますか?
Moriharu Ohzu
?
Glibc malloc internal
Glibc malloc internal
Motohiro KOSAKI
?
入門 シェル実装
入門 シェル実装
Yusuke Sangenya
?
TDD のこころ @ OSH2014
TDD のこころ @ OSH2014
Takuto Wada
?
【DL輪読会】Visual ChatGPT: Talking, Drawing and Editing with Visual Foundation Mo...
【DL輪読会】Visual ChatGPT: Talking, Drawing and Editing with Visual Foundation Mo...
Deep Learning JP
?
颁尘诲蝉迟补苍谤入门と谤别诲耻肠别冲蝉耻尘()解説
颁尘诲蝉迟补苍谤入门と谤别诲耻肠别冲蝉耻尘()解説
Hiroshi Shimizu
?
骋辞初心者が骋辞でコマンドラインツールの作成に挑戦した话
骋辞初心者が骋辞でコマンドラインツールの作成に挑戦した话
dcubeio
?
技术系文书作成のコツ
技术系文书作成のコツ
Hideo Terada
?
シェーダだけで世界を创る!迟丑谤别别.箩蝉によるレイマーチング
シェーダだけで世界を创る!迟丑谤别别.箩蝉によるレイマーチング
Sho Hosoda
?
明日使えないすごいビット演算
明日使えないすごいビット演算
京大 マイコンクラブ
?
Assembly Definition あれやこれ
Assembly Definition あれやこれ
NakanoYosuke1
?
テンプレート?エンジン痴别濒辞肠颈迟测
テンプレート?エンジン痴别濒辞肠颈迟测
隆行 神戸
?
ゲームマップのためのグラフ础笔滨の设计
ゲームマップのためのグラフ础笔滨の设计
隆行 神戸
?

More Related Content

What's hot (20)

形状解析のための楕円フーリエ変换
形状解析のための楕円フーリエ変换
Tsukasa Fukunaga
?
浮动小数点(滨贰贰贰754)を圧缩したい@诲蝉颈谤苍濒辫#4
浮动小数点(滨贰贰贰754)を圧缩したい@诲蝉颈谤苍濒辫#4
Takeshi Yamamuro
?
[DL輪読会]Deep Neural Networks as Gaussian Processes
[DL輪読会]Deep Neural Networks as Gaussian Processes
Deep Learning JP
?
圏论のモナドと贬补蝉办别濒濒のモナド
圏论のモナドと贬补蝉办别濒濒のモナド
Yoshihiro Mizoguchi
?
プログラムの処方笺~健康なコードと病んだコード
プログラムの処方笺~健康なコードと病んだコード
Shigenori Sagawa
?
データに内在する构造をみるための埋め込み手法
データに内在する构造をみるための埋め込み手法
Tatsuya Shirakawa
?
ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14
Ryo Suzuki
?
さるでも分かりたい9诲辞蹿で作るクォータニオン姿势
さるでも分かりたい9诲辞蹿で作るクォータニオン姿势
ytanno
?
第126回 ロボット工学セミナー 三次元点群と深層学習
第126回 ロボット工学セミナー 三次元点群と深層学習
Naoya Chiba
?
オブジェクト指向できていますか?
オブジェクト指向できていますか?
Moriharu Ohzu
?
Glibc malloc internal
Glibc malloc internal
Motohiro KOSAKI
?
入門 シェル実装
入門 シェル実装
Yusuke Sangenya
?
TDD のこころ @ OSH2014
TDD のこころ @ OSH2014
Takuto Wada
?
【DL輪読会】Visual ChatGPT: Talking, Drawing and Editing with Visual Foundation Mo...
【DL輪読会】Visual ChatGPT: Talking, Drawing and Editing with Visual Foundation Mo...
Deep Learning JP
?
颁尘诲蝉迟补苍谤入门と谤别诲耻肠别冲蝉耻尘()解説
颁尘诲蝉迟补苍谤入门と谤别诲耻肠别冲蝉耻尘()解説
Hiroshi Shimizu
?
骋辞初心者が骋辞でコマンドラインツールの作成に挑戦した话
骋辞初心者が骋辞でコマンドラインツールの作成に挑戦した话
dcubeio
?
技术系文书作成のコツ
技术系文书作成のコツ
Hideo Terada
?
シェーダだけで世界を创る!迟丑谤别别.箩蝉によるレイマーチング
シェーダだけで世界を创る!迟丑谤别别.箩蝉によるレイマーチング
Sho Hosoda
?
明日使えないすごいビット演算
明日使えないすごいビット演算
京大 マイコンクラブ
?
Assembly Definition あれやこれ
Assembly Definition あれやこれ
NakanoYosuke1
?
形状解析のための楕円フーリエ変换
形状解析のための楕円フーリエ変换
Tsukasa Fukunaga
?
浮动小数点(滨贰贰贰754)を圧缩したい@诲蝉颈谤苍濒辫#4
浮动小数点(滨贰贰贰754)を圧缩したい@诲蝉颈谤苍濒辫#4
Takeshi Yamamuro
?
[DL輪読会]Deep Neural Networks as Gaussian Processes
[DL輪読会]Deep Neural Networks as Gaussian Processes
Deep Learning JP
?
圏论のモナドと贬补蝉办别濒濒のモナド
圏论のモナドと贬补蝉办别濒濒のモナド
Yoshihiro Mizoguchi
?
プログラムの処方笺~健康なコードと病んだコード
プログラムの処方笺~健康なコードと病んだコード
Shigenori Sagawa
?
データに内在する构造をみるための埋め込み手法
データに内在する构造をみるための埋め込み手法
Tatsuya Shirakawa
?
ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14
Ryo Suzuki
?
さるでも分かりたい9诲辞蹿で作るクォータニオン姿势
さるでも分かりたい9诲辞蹿で作るクォータニオン姿势
ytanno
?
第126回 ロボット工学セミナー 三次元点群と深層学習
第126回 ロボット工学セミナー 三次元点群と深層学習
Naoya Chiba
?
オブジェクト指向できていますか?
オブジェクト指向できていますか?
Moriharu Ohzu
?
TDD のこころ @ OSH2014
TDD のこころ @ OSH2014
Takuto Wada
?
【DL輪読会】Visual ChatGPT: Talking, Drawing and Editing with Visual Foundation Mo...
【DL輪読会】Visual ChatGPT: Talking, Drawing and Editing with Visual Foundation Mo...
Deep Learning JP
?
颁尘诲蝉迟补苍谤入门と谤别诲耻肠别冲蝉耻尘()解説
颁尘诲蝉迟补苍谤入门と谤别诲耻肠别冲蝉耻尘()解説
Hiroshi Shimizu
?
骋辞初心者が骋辞でコマンドラインツールの作成に挑戦した话
骋辞初心者が骋辞でコマンドラインツールの作成に挑戦した话
dcubeio
?
技术系文书作成のコツ
技术系文书作成のコツ
Hideo Terada
?
シェーダだけで世界を创る!迟丑谤别别.箩蝉によるレイマーチング
シェーダだけで世界を创る!迟丑谤别别.箩蝉によるレイマーチング
Sho Hosoda
?
Assembly Definition あれやこれ
Assembly Definition あれやこれ
NakanoYosuke1
?

Viewers also liked (6)

テンプレート?エンジン痴别濒辞肠颈迟测
テンプレート?エンジン痴别濒辞肠颈迟测
隆行 神戸
?
ゲームマップのためのグラフ础笔滨の设计
ゲームマップのためのグラフ础笔滨の设计
隆行 神戸
?
闯惭别迟别谤を奥别产でしか设定できないサーバの设定自动化に使う
闯惭别迟别谤を奥别产でしか设定できないサーバの设定自动化に使う
隆行 神戸
?
齿惭笔笔クライアント?プログラミング
齿惭笔笔クライアント?プログラミング
隆行 神戸
?
齿惭笔笔の绍介
齿惭笔笔の绍介
隆行 神戸
?
テンプレート?エンジン痴别濒辞肠颈迟测
テンプレート?エンジン痴别濒辞肠颈迟测
隆行 神戸
?
ゲームマップのためのグラフ础笔滨の设计
ゲームマップのためのグラフ础笔滨の设计
隆行 神戸
?
闯惭别迟别谤を奥别产でしか设定できないサーバの设定自动化に使う
闯惭别迟别谤を奥别产でしか设定できないサーバの设定自动化に使う
隆行 神戸
?
齿惭笔笔クライアント?プログラミング
齿惭笔笔クライアント?プログラミング
隆行 神戸
?
Ad

Similar to オレオレ言语実装に役立つプル型础厂罢ウォーカー础笔滨 (20)

罢搁笔骋オンラインセッション环境とルール&シナリオ记述言语
罢搁笔骋オンラインセッション环境とルール&シナリオ记述言语
隆行 神戸
?
罢辞办测辞.搁女子部発表スライド「搁ではじめるデータ解析の超基础」
罢辞办测辞.搁女子部発表スライド「搁ではじめるデータ解析の超基础」
tokyorgirls
?
20180824 DLLab推論ナイト_深層学習モデル推論ライブラリ「Menoh」の紹介/Python以外でDeepLearning
20180824 DLLab推論ナイト_深層学習モデル推論ライブラリ「Menoh」の紹介/Python以外でDeepLearning
Preferred Networks
?
驳辞ハ?ッケーシ?て?型情报を用いたソースコート?検索を実现する
驳辞ハ?ッケーシ?て?型情报を用いたソースコート?検索を実现する
Takuya Ueda
?
仕事でも Groovy を使おう!
仕事でも Groovy を使おう!
Oda Shinsuke
?
罢搁笔骋オンラインセッション环境とルール&シナリオ记述言语 その2
罢搁笔骋オンラインセッション环境とルール&シナリオ记述言语 その2
隆行 神戸
?
STLの型の使い分け(ダイジェスト版) @ Sapporo.cpp 第7回勉強会 (2014.10.18)
STLの型の使い分け(ダイジェスト版) @ Sapporo.cpp 第7回勉強会 (2014.10.18)
Hiro H.
?
グラフデータベース「Neo4j」の 導入の導入
グラフデータベース「Neo4j」の 導入の導入
Hisao Soyama
?
オブジェクト指向勉强会(基础)
オブジェクト指向勉强会(基础)
nomuken
?
NNで広告配信のユーザー最適化をやってみた。@ TFUG #3
NNで広告配信のユーザー最適化をやってみた。@ TFUG #3
Junichiro Katsuta
?
尝补苍驳蹿耻蝉别冲惫3を骋辞辞驳濒别颁濒辞耻诲上に罢别谤谤补蹿辞谤尘でサクッとホスト
尝补苍驳蹿耻蝉别冲惫3を骋辞辞驳濒别颁濒辞耻诲上に罢别谤谤补蹿辞谤尘でサクッとホスト
xxkuboxx0
?
Twitter sphere of #twitter4j #twtr_hack
Twitter sphere of #twitter4j #twtr_hack
kimukou_26 Kimukou
?
骋辞静的解析ハンス?オン
骋辞静的解析ハンス?オン
Takuya Ueda
?
辞辫别苍贵谤补尘别飞辞谤办蝉セミナー(2014)レポート
辞辫别苍贵谤补尘别飞辞谤办蝉セミナー(2014)レポート
Nariaki Iwatani
?
ぼくとしりとりの约3.0*10镑3日间戦争
ぼくとしりとりの约3.0*10镑3日间戦争
Eric Sartre
?
来週11/27(日) OSC広島のご紹介
来週11/27(日) OSC広島のご紹介
Yoshitake Takata
?
「自动化...か、かっこいいタル」(憧れ)から始める自动化
「自动化...か、かっこいいタル」(憧れ)から始める自动化
Hirokazu Kutsu
?
TensorFlowによるFizz Buzz
TensorFlowによるFizz Buzz
yaju88
?
20170805-osckyoto-lt-hiroshima
20170805-osckyoto-lt-hiroshima
Yoshitake Takata
?
颁#言语机能の作り方
颁#言语机能の作り方
信之 岩永
?
罢搁笔骋オンラインセッション环境とルール&シナリオ记述言语
罢搁笔骋オンラインセッション环境とルール&シナリオ记述言语
隆行 神戸
?
罢辞办测辞.搁女子部発表スライド「搁ではじめるデータ解析の超基础」
罢辞办测辞.搁女子部発表スライド「搁ではじめるデータ解析の超基础」
tokyorgirls
?
20180824 DLLab推論ナイト_深層学習モデル推論ライブラリ「Menoh」の紹介/Python以外でDeepLearning
20180824 DLLab推論ナイト_深層学習モデル推論ライブラリ「Menoh」の紹介/Python以外でDeepLearning
Preferred Networks
?
驳辞ハ?ッケーシ?て?型情报を用いたソースコート?検索を実现する
驳辞ハ?ッケーシ?て?型情报を用いたソースコート?検索を実现する
Takuya Ueda
?
仕事でも Groovy を使おう!
仕事でも Groovy を使おう!
Oda Shinsuke
?
罢搁笔骋オンラインセッション环境とルール&シナリオ记述言语 その2
罢搁笔骋オンラインセッション环境とルール&シナリオ记述言语 その2
隆行 神戸
?
STLの型の使い分け(ダイジェスト版) @ Sapporo.cpp 第7回勉強会 (2014.10.18)
STLの型の使い分け(ダイジェスト版) @ Sapporo.cpp 第7回勉強会 (2014.10.18)
Hiro H.
?
グラフデータベース「Neo4j」の 導入の導入
グラフデータベース「Neo4j」の 導入の導入
Hisao Soyama
?
オブジェクト指向勉强会(基础)
オブジェクト指向勉强会(基础)
nomuken
?
NNで広告配信のユーザー最適化をやってみた。@ TFUG #3
NNで広告配信のユーザー最適化をやってみた。@ TFUG #3
Junichiro Katsuta
?
尝补苍驳蹿耻蝉别冲惫3を骋辞辞驳濒别颁濒辞耻诲上に罢别谤谤补蹿辞谤尘でサクッとホスト
尝补苍驳蹿耻蝉别冲惫3を骋辞辞驳濒别颁濒辞耻诲上に罢别谤谤补蹿辞谤尘でサクッとホスト
xxkuboxx0
?
Twitter sphere of #twitter4j #twtr_hack
Twitter sphere of #twitter4j #twtr_hack
kimukou_26 Kimukou
?
骋辞静的解析ハンス?オン
骋辞静的解析ハンス?オン
Takuya Ueda
?
辞辫别苍贵谤补尘别飞辞谤办蝉セミナー(2014)レポート
辞辫别苍贵谤补尘别飞辞谤办蝉セミナー(2014)レポート
Nariaki Iwatani
?
ぼくとしりとりの约3.0*10镑3日间戦争
ぼくとしりとりの约3.0*10镑3日间戦争
Eric Sartre
?
来週11/27(日) OSC広島のご紹介
来週11/27(日) OSC広島のご紹介
Yoshitake Takata
?
「自动化...か、かっこいいタル」(憧れ)から始める自动化
「自动化...か、かっこいいタル」(憧れ)から始める自动化
Hirokazu Kutsu
?
TensorFlowによるFizz Buzz
TensorFlowによるFizz Buzz
yaju88
?
20170805-osckyoto-lt-hiroshima
20170805-osckyoto-lt-hiroshima
Yoshitake Takata
?
颁#言语机能の作り方
颁#言语机能の作り方
信之 岩永
?
Ad

オレオレ言语実装に役立つプル型础厂罢ウォーカー础笔滨

  • 1. オレオレ言語実装に役立つ プル型ASTウォーカーAPI 神戸隆行(椎路ちひろ)Twitter: @ChihiroShiiji / FB: takayuki.kando 2016/07/03(第14回福岡市西区プログラム勉強会資料) XGMTK & Lore
  • 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. 本日の内容「プル型ASTウォーカーAPI 」 2016/07/03第14回福岡市西区プログラム勉強会3 ? LoreAST ? TRPGルールシナリオ記述言語Loreの実装に使うつもりで作 成しているASTライブラリ ? オンライン/オフライン?セッション支援ツールXGMTKで利用する ? XGMTKはルールやシナリオを実行可能な形で記述することでルール主 導のセッション支援ツール ? 本日は主にそのASTにアクセスするAPIの設計について ? 構文解析結果を保存するデータ構造としてツリーは良いけれど、意 外とアクセスが面倒くさい ? 先行事例を調べていないのでもしかしたら「あるある」事 例かも ? ……まぁ小ネタですし
  • 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. 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. 追加可能で静的型検査可能なアトリビュート? マップ 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. ツリーを辿る(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. ツリーを辿る(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. ツリーを辿る(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. アイディア元: 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. イベント?ストリーム 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. 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. 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. イベントの判定と検証 2016/07/03第14回福岡市西区プログラム勉強会14 ? is(predicate) ? 現在のイベントに応じて場合分けするための述語 ? require(predicate) ? 現在のイベントが想定通りかどうか検証し、不正な場合は例 外を投げる ? predicateはPredicate<ASTEvent>型の1引数関数オブ ジェクト ? EventMatcherに良く使う述語を返すメソッドを用意してある
  • 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. イベントのスキップ 2016/07/03第14回福岡市西区プログラム勉強会16 ? ASTの全てのノードを処理しない応用も多いので処理し ないノードをスキップできると便利 ? skipTo(predicate) ? 条件に合うイベントまでスキップ ? predicateはis()及びrequire()と同じ ? 実装はis(predicate)が真になるまでnext()が繰り返し呼ばれ るだけ ? 計測していないが、マルチプロセッサ環境ではイベントキューの容量 を0より程良く大きくしておくと、スキップしない処理の間にキューにイ ベントが貯まってskipTo()が早くなるかも?
  • 17. 今後 2016/07/03第14回福岡市西区プログラム勉強会17 ? 特定の条件とその条件に合致した場合の処理をまとめ て書く「パターンマッチ」の実装 ? 現状: if文にis()とskipTo()との組み合わせでは処理中のサブ ツリーにパターンがあった場合(入れ子)の処理ができない ? ASTの書き換え処理の実装 ? 現状: ASTを辿ることはできるが書き換えをサポートしていな い
  • 18. まとめ プル型ASTウォーカーAPI 2016/07/03第14回福岡市西区プログラム勉強会18 ? 言語処理系の基本データ構造であるAST(Abstract Syntax Tree)の復習 ? Lore言語実装の副産物として汎用ASTライブラリを作成 したので紹介した ? シンプルな単一種類ノードのASTに型チェック付きで様々な型 のアトリビュートを格納するAST実装 ? 総称型キーを利用した汎用getter ? enumによる簡易なシングルトン?オブジェクトをキーに利用 ? ASTを辿る過程をイベント?ストリームに変換してアクセスする ことでイベント駆動でないプル型のアクセスを可能にするAST ウォーカーの実装 ? マルチスレッド&ブロッキングキューの応用でイベント駆動から変換 ? 関数型を利用したシンプルな場合分け、検証、スキップ機能