LoginSignup
0
1

More than 3 years have passed since last update.

C++11 PEG パーザーライブラリ PEGTL のメモ

Posted at

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 を記述してテストしておくのがよいかもしれません.

TODO

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1