パラメトリックパーサ

既に Spirit フレームワークの動的な性質の手がかりは得ている。 この性能は Spirit の潜在的なゴールにとって基盤となるものである。 ダイナミズムは構文解析処理に適用されたとき非常に強力な概念となる。 この概念を、実行時にパラメトリックなパーサへとさらに推し進める。 これによって、EBNF構文のみでは為し得なかった構文解析タスクを扱うことができる。

ちょっとした秘訣

boost 配布物の一部にあまり目立たないboost::refというちょっとした代物がある。 これはSpiritのプリミティブパーサと一緒に用いられるとかなり強力な獣となる。 次のような、文字列と文字リテラルで作られたSpiritのプリミティブパーサはよく見かけられる:

    ch_p('A')
    range_p('A', 'Z')
    str_p("Hello World")

str_pは文字列の始めと終わりを指す二つのイテレータを受け付ける、第二の形式を持っている:

    char const* first = "My oh my";
    char const* last = first + std::strlen(first);

    str_p(first, last)

boost::refを上手く使えることは、自明とは言い難い:

    char ch = 'A';
    char from = 'A';
    char to = 'Z';

    ch_p(boost::ref(ch))
    range_p(boost::ref(from), boost::ref(to))

boost::refが使われるとch_prange_pへの実際のパラメータは参照で保持される。 これは、 chfromおよびtoの値をいつでも変更でき、 対応するch_prange_pパーサはそれらの動的な値に従うということを意味する。

str_pについてはどうだろうか?

str_pの第一の形式(単一引数の形)はヌル終端を持つ文字列定数のために用意されている。 一方で第二の形式(二つの引数first/lastイテレータの形)は次のように用いられる:

    char const* first = "My oh my";
    char const* last = first + std::strlen(first);

    str_p(boost::ref(first), boost::ref(last))
おっと、chseq_pをお忘れなく。上記の全てのことは、このあまり使われないプリミティブにも同じように適用される。

関数パラメトリックパーサ

これをさらに深化させ、 Spirit はプリミティブの関数バージョンを含んでいる。 関数バージョンは、文字や文字列あるいは文字や文字列への(boost::refを用いた)参照ではなく、関数やファンクタを受け取る。

f_chlit と f_ch_p

chlitの関数バージョン。 このパーサは関数またはファンクタを取る。 関数は、以下と互換性のあるインタフェースを持つよう要求される:

    CharT func()

ここでCharTは文字型である(例えばcharintwchar_t)。

ファンクタは、以下と互換性のあるインターフェイスを持つよう要求される:

    struct functor
    {
        CharT operator()() const;
    };

ここでCharTは文字型である(例えばcharintwchar_t)。

説明のための例:

    struct X
    {
        char operator()() const
        { return 'X'; }
    };

さて X を f_chlit パーサを使うために使うことが出来る:

    f_ch_p(X())

f_range と f_range_p

rangeの関数バージョン。 このパーサは上述のインタフェースと互換性のある関数またはファンクタを取る。 違いは、f_range(とf_range_p)が二つのファンクタを要求することである。 一つは範囲の始端、もう一つは終端である。

f_chseq と f_chseq_p

chseqの関数バージョン。 このパーサは二つの関数またはファンクタを取る。 一つは開始イテレータで、もう一つは終了イテレータである。 関数は、以下と互換性のあるインタフェースを持つよう要求される:

    IteratorT func()

ここでIteratorTはイテレータの型である(例えばchar const*wchar_t const*)。

ファンクタは、以下と互換性のあるインタフェースを持つよう要求される:

    struct functor
    {
        IteratorT operator()() const;
    };

ここでIteratorTはイテレータの型である(例えばchar const*wchar_t const*)。

f_strlit と f_str_p

strlitの関数バージョン。 このパーサは、f_chseqが要求するものと同じインタフェースを持つ二つの関数またはファンクタを受け取る。



このドキュメントの対象: Boost Version 1.30.0
最新版ドキュメント(英語)