Sprout.Weed で複数文字の取得

weed::char_ と weed::lim を利用して複数の文字のパースを行います。

[ソース]

#define SPROUT_CONFIG_SUPPORT_TEMPORARY_CONTAINER_ITERATION
#include <sprout/weed.hpp>


template<typename Char, std::size_t N, typename Parser>
constexpr bool
check_parser(Char const(&str)[N], Parser&& parser){
    using sprout::weed::parse;
    return parse(str, str+N-1, sprout::forward<Parser>(parser)).success();
}

template<typename Char, std::size_t N, typename Parser, typename Attr>
constexpr bool
check_attr(Char const(&str)[N], Parser&& parser, Attr&& attr){
    using sprout::weed::parse;
    return parse(str, str+N-1, sprout::forward<Parser>(parser)).attr() == attr;
}

int
main(){
    namespace w = sprout::weed;

    // 4文字にマッチするパーサ
    // 文字幅にマッチするので、文字数が4文字でなくても問題ない
    static constexpr auto char4 = *w::lim<4>(w::char_);

    static_assert(check_parser("homu", char4), "");
    static_assert(check_parser("madohomu", char4), "");
    static_assert(check_parser("ho", char4), "");

    // デフォルトの設定では先頭からマッチし、はみ出した部分が切り捨てられる
    static_assert(check_attr("madohomu", char4, "mado"), "");

    return 0;
}


注意する点はマッチする文字数は関係なく、パースした結果が指定した文字数になることです。
どの位置でマッチするのかは、weed::limited::category で指定することが出来ます。

static_assert(check_attr("abcd", *w::lim<3>(w::char_, w::limited::discard),  "abc"), "");
static_assert(check_attr("abcd", *w::lim<3>(w::char_, w::limited::circular), "bcd"), "");
static_assert(check_attr("abcd", *w::lim<3>(w::char_, w::limited::stopover), "abc"), "");


まぁここら辺はうまく説明が出来ないので実際に書いてみるのがいいと思います。

[コンパイラ]

  • g++ (GCC) 4.7.0 20111210 (experimental)