by shigemk2

当面は技術的なことしか書かない

Boost.Spirit.QiとLLVM APIで遊ぼう #kbkz_tech

kbkz.connpass.com

Boost.Sprit.Qi

LLVM API

github.com

Boost.Sprit.Qi

  • Boostに含まれる構文解析のためのライブラリ
  • 演算子オーバーロードを巧みに使い、構文解析器が出来上がる
  • 楽に書ける

使い方

  • 構文解析を2つの関数を使って行う phrase_parseとparse

コード例 f:id:shigemk2:20150517145915p:plain

解析が成功したらsuccessがtrue it == input.end()になる

ルール

  • 文法は1つ以上のルールで構成
  • boost::sprit::qi::ruleのインスタンス
  • セマンティックアクションと呼ばれる。
  • 渡すのは関数オブジェクトでも可

文字種

  • いろいろある

ルール同士の結合

  • 演算子をつかう
  • leximで囲む

ルールの繰り返しと選択

  • 正規表現みたいな感じで使えるよ。

Boost.Phoenixの概要

  • プレースホルダーと組み合わせると、演算子オーバーロードを駆使して目的の関数オブジェクトをつくってくれる
  • 基本的にプレースホルダーを使ってやりたいことを書けばおーけー
  • 複数の処理を行いたい場合は、カンマで区切る
  • しかし、一部の処理は記法が違うので注意

構造体やクラスへのアクセス 複雑な文法定義

複雑な文法の場合は、別途構造体等に定義してそこに入れたほうがよいかも

f:id:shigemk2:20150517150805p:plain

ASTを作る

ルールを書き、それにたいするセマンティックアクション内でルールに対応するASTのインスタンスを生成して返す

f:id:shigemk2:20150517150854p:plain

ASTをネイティブコードに変換しないといけない

LLVM APIをつかえば簡単なのでは?

LLVMとは

  • オープンソースのコンパイラ基盤
  • IRへの変換プログラムだけ書けばどんなコンパイラでも理論上は可能

LLVM IRを出力する

  • LLVM IRはC++においてはクラスのインスタンスで表現されるが、インスタンスを作る方法もモノもまちまち
  • IRBuilderを使う
  • CreateAdd CreateCall

IRBuilder

f:id:shigemk2:20150517151208p:plain

ASTでなめていってIRを生成する

LLVM IRのファイルへの出力

  • LLVM IRのC++による表現が出来上がったら、ファイルへ出力する f:id:shigemk2:20150517151322p:plain

ネイティブコードへの変換

  • llvm-asコマンドを使う

全体の流れ

  • ソースコードを読み込む
  • Boost.Sprit.QiによってAST作成
  • ASTからLLVM IRをつくる
  • LLVM IRをファイル出力
  • ネイティブコード変換

まとめ

  • LLVM APIとQiを組み合わせてプログラミングの処理系を作成できる
  • IRの形にすればLLVMに所属している最適化が使えるので本質のみに集中
  • この組み合わせでBFの派生じゃないネタ言語を作ろう

質疑

  • lexとyacc使えばよいのでは