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 + -
显示快捷键?