Version 2.x ですと C++11 で動きます.
利点
template プログラミングであるが, コンパイルが早めな気がする.
すくなくとも cpp-peglib よりはコンパイルが早い感じがします.
ヘッダーオンリー.
使いかた
ルールは template で定義します.
using namespace tao::pegtl;
struct sign : one< '+', '-' > {};
struct integer : seq< opt< sign >, plus< digit > > {};
<
, >
の間のスペースは空いていても空いていなくても問題ありません.
最初はちょっと手間取りますが, サンプルなど見て慣れればだいたい C++11 の仕組みで書けます.
文字列に対して parse する.
memory_input で入力データを作ってから parse に渡します.
std::string uri = ...;
pegtl::memory_input input( uri, "uri" );
pegtl::parse< grammar, uri::action >( input, *this );
ファイルや stdin から入力を受け付ける関数もあります.
action を設定する
ルールにマッチしたときに呼び出す関数(callback)も template で定義します.
// 必須
template< typename Rule > struct action {};
// 個々のルールに対して apply でアクションを定義.
template<>
struct action< pegtl::uri::opt_userinfo >
{
template< typename Input >
static void apply( const Input& in, URI& uri )
{
if( !in.empty() ) {
uri.userinfo = std::string( in.begin(), in.size() - 1 );
}
}
};
まずはベースとなる action のテンプレートを定義し, そのあと各ルールごとに template を定義します. ベースの template を定義していないとうまく動きません(なにも起こらない)ので注意です.
また, apply の第二引数と, parse で渡す型が違うととこれもまた何も起こらないので注意です.
e.g.
std::string ctx;
// action は `URI` に対して定義しているので, なにもおこらない.
pegtl::parse< grammar, uri::action >( input, ctx );
問題点
template programming なので, パターンマッチしないときはエラーを出さず何も処理されないので注意です.
したがってデバッグはちょっとめんどいかもしれません. cpp-peglib などで先に grammar を記述してテストしておくのがよいかもしれません.