Sprout.Weed で複数の文字列をパースする場合に文字列が連結されるのを回避する
さて、
homu:mado
のような『:』区切りの構文をパースする場合、
namespace weed = sprout::weed; static constexpr auto parser = *weed::lim<4>(weed::char_ - ':') >> ":" >> *weed::lim<4>(weed::char_);
のようなパーサを記述すると思います。
しかし、このパーサでは文字列が連結されて結果が返ってきます。
static constexpr auto parser = *weed::lim<4>(weed::char_ - ':') >> ":" >> *weed::lim<4>(weed::char_); static_assert(parse("homu:mado", parser), ""); static_assert(parse("homu:mado", parser) == "homumado", "");
これを回避するために weed::as_tuple を使用します。
[ソース]
#define SPROUT_CONFIG_SUPPORT_TEMPORARY_CONTAINER_ITERATION #include <sprout/weed.hpp> template<typename Parsed> struct parsed_holder{ constexpr operator bool() const{ return parsed.success(); } template<typename T> constexpr bool operator ==(T&& t) const{ return parsed.attr() == t; } Parsed parsed; }; template<typename Char, std::size_t N, typename Parser> constexpr auto parse(Char const(&str)[N], Parser&& parser) ->parsed_holder<decltype( sprout::weed::parse(str, str+N-1, sprout::forward<Parser>(parser)) )>{ return { sprout::weed::parse(str, str+N-1, sprout::forward<Parser>(parser)) }; } int main(){ using sprout::make_tuple; namespace w = sprout::weed; static constexpr auto item = w::as_tuple[*w::lim<4>(w::char_ - ':')]; static_assert(parse("homu:mado", item >> ':' >> item), ""); static_assert(parse("homu:mado", item >> ':' >> item) == make_tuple("homu", "mado"), ""); return 0; }