traverse_tests.cpp

来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 519 行 · 第 1/2 页

CPP
519
字号
    BOOST_TEST(c == 'b');}///////////////////////////////////////////////////////////////////////////////////  The following is a tracing identity_transform traverse metafunction/////////////////////////////////////////////////////////////////////////////////class trace_identity_transform:   public transform_policies<trace_identity_transform> {public:    typedef trace_identity_transform self_t;    typedef transform_policies<trace_identity_transform> base_t;    template <typename ParserT, typename EnvT>    typename parser_traversal_plain_result<self_t, ParserT, EnvT>::type    generate_plain(ParserT const &parser_, EnvT const &env) const    {        OSSTREAM strout;        strout            << EnvT::node                << ": plain ("                << EnvT::level << ", "                << EnvT::index                << "): "            << parser_name(parser_);        traces.push_back(GETSTRING(strout));        return this->base_t::generate_plain(parser_, env);    }    template <typename UnaryT, typename SubjectT, typename EnvT>    typename parser_traversal_unary_result<self_t, UnaryT, SubjectT, EnvT>::type    generate_unary(UnaryT const &unary_, SubjectT const &subject_,        EnvT const &env) const    {        OSSTREAM strout;        strout            << EnvT::node << ": unary ("                << EnvT::level                << "): "            << parser_name(unary_);        traces.push_back(GETSTRING(strout));        return this->base_t::generate_unary(unary_, subject_, env);    }    template <typename ActionT, typename SubjectT, typename EnvT>    typename parser_traversal_action_result<self_t, ActionT, SubjectT, EnvT>::type    generate_action(ActionT const &action_, SubjectT const &subject_,        EnvT const &env) const    {        OSSTREAM strout;        strout            << EnvT::node << ": action("                << EnvT::level                << "): "            << parser_name(action_);        traces.push_back(GETSTRING(strout));        return this->base_t::generate_action(action_, subject_, env);    }    template <typename BinaryT, typename LeftT, typename RightT, typename EnvT>    typename parser_traversal_binary_result<self_t, BinaryT, LeftT, RightT, EnvT>::type    generate_binary(BinaryT const &binary_, LeftT const& left_,        RightT const& right_, EnvT const &env) const    {        OSSTREAM strout;        strout            << EnvT::node << ": binary("                << EnvT::level                << "): "            << parser_name(binary_);        traces.push_back(GETSTRING(strout));        return this->base_t::generate_binary(binary_, left_, right_, env);    }    std::vector<string> const &get_output() const { return traces; }private:    mutable std::vector<std::string> traces;};template <typename ParserT>voidpost_order_trace_test(ParserT const &parser_, char const *first[], size_t cnt){// traversetrace_identity_transform trace_vector;    post_order::traverse(trace_vector, parser_);// The following two re-find loops ensure, that both string arrays contain the// same entries, only their order may differ. The differences in the trace// string order is based on the different parameter evaluation order as it is// implemented by different compilers.// re-find all trace strings in the array of expected stringsstd::vector<std::string>::const_iterator it = trace_vector.get_output().begin();std::vector<std::string>::const_iterator end = trace_vector.get_output().end();    BOOST_TEST(cnt == trace_vector.get_output().size());    for (/**/;  it != end; ++it)    {        if (std::find(first, first + cnt, *it) == first + cnt)            cerr << "node in question: " << *it << endl;        BOOST_TEST(std::find(first, first + cnt, *it) != first + cnt);    }// re-find all expected strings in the vector of trace stringsstd::vector<std::string>::const_iterator begin = trace_vector.get_output().begin();char const *expected = first[0];    for (size_t i = 0; i < cnt; expected = first[++i])    {        if (std::find(begin, end, std::string(expected)) == end)            cerr << "node in question: " << expected << endl;        BOOST_TEST(std::find(begin, end, std::string(expected)) != end);    }}#if defined(_countof)#undef  _countof#endif#define _countof(x) (sizeof(x)/sizeof(x[0]))voidtraverse_trace_tests(){const char *test_result1[] = {        "0: plain (1, 0): chlit('a')",        "1: plain (1, 1): chlit('b')",        "2: binary(0): sequence[chlit('a'), chlit('b')]",    };    post_order_trace_test(        ch_p('a') >> 'b',        test_result1, _countof(test_result1)    );char c = 0;// test: ((a >> b) >> c) >> dconst char *test_result2[] = {        "0: plain (4, 0): chlit('a')",        "1: unary (3): kleene_star[chlit('a')]",        "2: plain (4, 1): chlit('b')",        "3: action(3): action[chlit('b')]",        "4: binary(2): sequence[kleene_star[chlit('a')], action[chlit('b')]]",        "5: plain (2, 2): chlit('c')",        "6: binary(1): sequence[sequence[kleene_star[chlit('a')], action[chlit('b')]], chlit('c')]",        "7: plain (2, 3): chlit('d')",        "8: unary (1): optional[chlit('d')]",        "9: binary(0): sequence[sequence[sequence[kleene_star[chlit('a')], action[chlit('b')]], chlit('c')], optional[chlit('d')]]",    };    post_order_trace_test(        ((*ch_p('a') >> ch_p('b')[assign_a(c)]) >> 'c') >> !ch_p('d'),        test_result2, _countof(test_result2)    );// test: (a >> (b >> c)) >> dconst char *test_result3[] = {        "0: plain (3, 0): chlit('a')",        "1: unary (2): kleene_star[chlit('a')]",        "2: plain (4, 1): chlit('b')",        "3: action(3): action[chlit('b')]",        "4: plain (3, 2): chlit('c')",        "5: binary(2): sequence[action[chlit('b')], chlit('c')]",        "6: binary(1): sequence[kleene_star[chlit('a')], sequence[action[chlit('b')], chlit('c')]]",        "7: plain (2, 3): chlit('d')",        "8: unary (1): optional[chlit('d')]",        "9: binary(0): sequence[sequence[kleene_star[chlit('a')], sequence[action[chlit('b')], chlit('c')]], optional[chlit('d')]]",    };    post_order_trace_test(        (*ch_p('a') >> (ch_p('b')[assign_a(c)] >> 'c')) >> !ch_p('d'),        test_result3, _countof(test_result3)    );// test: a >> (b >> (c >> d))const char *test_result4[] = {        "0: plain (2, 0): chlit('a')",        "1: unary (1): kleene_star[chlit('a')]",        "2: plain (3, 1): chlit('b')",        "3: action(2): action[chlit('b')]",        "4: plain (3, 2): chlit('c')",        "5: plain (4, 3): chlit('d')",        "6: unary (3): optional[chlit('d')]",        "7: binary(2): sequence[chlit('c'), optional[chlit('d')]]",        "8: binary(1): sequence[action[chlit('b')], sequence[chlit('c'), optional[chlit('d')]]]",        "9: binary(0): sequence[kleene_star[chlit('a')], sequence[action[chlit('b')], sequence[chlit('c'), optional[chlit('d')]]]]",    };    post_order_trace_test(        *ch_p('a') >> (ch_p('b')[assign_a(c)] >> ('c' >> !ch_p('d'))),        test_result4, _countof(test_result4)    );// test: a >> ((b >> c) >> d)const char *test_result5[] = {        "0: plain (2, 0): chlit('a')",        "1: unary (1): kleene_star[chlit('a')]",        "2: plain (4, 1): chlit('b')",        "3: action(3): action[chlit('b')]",        "4: plain (3, 2): chlit('c')",        "5: binary(2): sequence[action[chlit('b')], chlit('c')]",        "6: plain (3, 3): chlit('d')",        "7: unary (2): optional[chlit('d')]",        "8: binary(1): sequence[sequence[action[chlit('b')], chlit('c')], optional[chlit('d')]]",        "9: binary(0): sequence[kleene_star[chlit('a')], sequence[sequence[action[chlit('b')], chlit('c')], optional[chlit('d')]]]",    };    post_order_trace_test(        *ch_p('a') >> ((ch_p('b')[assign_a(c)] >> 'c') >> !ch_p('d')),        test_result5, _countof(test_result5)    );// test: (a >> b) >> (c >> d)const char *test_result6[] = {        "0: plain (3, 0): chlit('a')",        "1: unary (2): kleene_star[chlit('a')]",        "2: plain (3, 1): chlit('b')",        "3: action(2): action[chlit('b')]",        "4: binary(1): sequence[kleene_star[chlit('a')], action[chlit('b')]]",        "5: plain (2, 2): chlit('c')",        "6: plain (3, 3): chlit('d')",        "7: unary (2): optional[chlit('d')]",        "8: binary(1): sequence[chlit('c'), optional[chlit('d')]]",        "9: binary(0): sequence[sequence[kleene_star[chlit('a')], action[chlit('b')]], sequence[chlit('c'), optional[chlit('d')]]]",    };    post_order_trace_test(        (*ch_p('a') >> ch_p('b')[assign_a(c)]) >> ('c' >> !ch_p('d')),        test_result6, _countof(test_result6)    );}///////////////////////////////////////////////////////////////////////////////////  Main/////////////////////////////////////////////////////////////////////////////////intmain(){    traverse_identity_tests();    traverse_trace_tests();    return boost::report_errors();}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?