Boost.Spirit.Qi の Parser を保持

[ソース]

#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/include/io.hpp>

namespace qi     = boost::spirit::qi;
namespace fusion = boost::fusion;

template <typename P>
void test_parser(char const* input, P const& p, bool full_match = true){
    using boost::spirit::qi::parse;

    char const* f(input);
    char const* l(f + strlen(f));
    if (parse(f, l, p) && (!full_match || (f == l)))
        std::cout << "ok" << std::endl;
    else
        std::cout << "fail" << std::endl;
}

template <typename P, typename T>
void test_parser_attr(
char const* input, P const& p, T& attr, bool full_match = true){
    using boost::spirit::qi::parse;

    char const* f(input);
    char const* l(f + strlen(f));
    if (parse(f, l, p, attr) && (!full_match || (f == l)))
        std::cout << "ok" << std::endl;
    else
        std::cout << "fail" << std::endl;
}

int
main(){
    qi::rule<char const*, int()> int_ = qi::int_;
    test_parser("100", int_);
    
    qi::rule<char const*, fusion::vector<int, double>()>
        int_double = qi::int_ >> ":" >> qi::double_;
    fusion::vector<int, double> result;
    test_parser_attr("100:3.14", int_double, result);
    std::cout << result << std::endl;
    
    return 0;
}

[出力]

ok
ok
(100 3.14)


qi::rule を使用すれば思ったよりも簡単に保持できますね。
template 引数なんかは、下記を参照して下さい。

[boost]

  • ver 1.47.0