Boost.Sprit.Qi
LLVM API
Boost.Sprit.Qi
- Boostに含まれる構文解析のためのライブラリ
- 演算子オーバーロードを巧みに使い、構文解析器が出来上がる
- 楽に書ける
使い方
- 構文解析を2つの関数を使って行う phrase_parseとparse
コード例
解析が成功したらsuccessがtrue it == input.end()になる
ルール
- 文法は1つ以上のルールで構成
- boost::sprit::qi::ruleのインスタンス
- セマンティックアクションと呼ばれる。
- 渡すのは関数オブジェクトでも可
文字種
- いろいろある
ルール同士の結合
- 演算子をつかう
- leximで囲む
ルールの繰り返しと選択
- 正規表現みたいな感じで使えるよ。
Boost.Phoenixの概要
- プレースホルダーと組み合わせると、演算子オーバーロードを駆使して目的の関数オブジェクトをつくってくれる
- 基本的にプレースホルダーを使ってやりたいことを書けばおーけー
- 複数の処理を行いたい場合は、カンマで区切る
- しかし、一部の処理は記法が違うので注意
構造体やクラスへのアクセス 複雑な文法定義
複雑な文法の場合は、別途構造体等に定義してそこに入れたほうがよいかも
ASTを作る
ルールを書き、それにたいするセマンティックアクション内でルールに対応するASTのインスタンスを生成して返す
ASTをネイティブコードに変換しないといけない
LLVM APIをつかえば簡単なのでは?
LLVMとは
- オープンソースのコンパイラ基盤
- IRへの変換プログラムだけ書けばどんなコンパイラでも理論上は可能
LLVM IRを出力する
- LLVM IRはC++においてはクラスのインスタンスで表現されるが、インスタンスを作る方法もモノもまちまち
- IRBuilderを使う
- CreateAdd CreateCall
IRBuilder
ASTでなめていってIRを生成する
LLVM IRのファイルへの出力
- LLVM IRのC++による表現が出来上がったら、ファイルへ出力する
ネイティブコードへの変換
- llvm-asコマンドを使う
全体の流れ
- ソースコードを読み込む
- Boost.Sprit.QiによってAST作成
- ASTからLLVM IRをつくる
- LLVM IRをファイル出力
- ネイティブコード変換
まとめ
- LLVM APIとQiを組み合わせてプログラミングの処理系を作成できる
- IRの形にすればLLVMに所属している最適化が使えるので本質のみに集中
- この組み合わせでBFの派生じゃないネタ言語を作ろう
質疑
- lexとyacc使えばよいのでは
Q. lex/yaccのようなツールはC++にないの?あるいは言語内DSL的な外部ツールと比べてどうなの? A. 外部ツールは、独自の記法と、セマンティックアクションのC++的なコードが混在するのがよくないと思う #kbkz_tech
— saka1 (@saka1_p) 2015, 5月 17