/*============================================================================= Copyright (c) 2001-2003 Joel de Guzman http://spirit.sourceforge.net/ Use, modification and distribution is subject to the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ #include #include #include #include #include #include using namespace BOOST_SPIRIT_CLASSIC_NS; using namespace phoenix; /////////////////////////////////////////////////////////////////////////////// // // Closure tests // /////////////////////////////////////////////////////////////////////////////// struct my_closure1 : BOOST_SPIRIT_CLASSIC_NS::closure { member1 val; }; struct my_closure2 : BOOST_SPIRIT_CLASSIC_NS::closure { member1 ch; }; struct my_closure3 : BOOST_SPIRIT_CLASSIC_NS::closure { member1 ch; }; struct X { int a; int b; }; #if defined(BOOST_SPIRIT_DEBUG) // If debugging is switched on, all closure members should have a // corresponding output streaming operator std::ostream & operator<< (std::ostream& o, X const &x) { o << "X(" << x.a << ", " << x.b << ")"; return o; } #endif // defined(BOOST_SPIRIT_DEBUG) struct my_closure4 : BOOST_SPIRIT_CLASSIC_NS::closure { member1 x; }; // MWCW8.3 needs the default constructor here or it won't compile. // It should not be needed. struct Y { Y() {} Y(int) {} }; #if defined(BOOST_SPIRIT_DEBUG) // If debugging is switched on, all closure members should have a // corresponding output streaming operator std::ostream & operator<< (std::ostream& o, Y const &/*x*/) { o << "Y"; return o; } #endif // defined(BOOST_SPIRIT_DEBUG) struct my_closure5 : BOOST_SPIRIT_CLASSIC_NS::closure { member1 y; }; struct my_closure6 : BOOST_SPIRIT_CLASSIC_NS::closure { member1 x; member2 y; member3 z; }; void closure_tests() { rule num_list; double n; num_list = ( real_p[num_list.val = arg1] >> *(',' >> real_p[num_list.val += arg1]) ) [var(n) = num_list.val]; parse_info pi; pi = parse("123, 456, 789", num_list, space_p); BOOST_TEST(pi.hit); BOOST_TEST(pi.full); BOOST_TEST(n == 123 + 456 + 789); rule, my_closure2::context_t> rev; rev = anychar_p[rev.ch = arg1] >> !rev >> f_ch_p(rev.ch); pi = parse("xyzzyx", rev); BOOST_TEST(pi.hit); BOOST_TEST(pi.full); pi = parse("xyzczyx", rev); BOOST_TEST(!pi.hit); subrule<0, my_closure3::context_t> rev2; pi = parse("atoyyota", rev2 = anychar_p[rev2.ch = arg1] >> !rev2 >> f_ch_p(rev2.ch) ); BOOST_TEST(pi.hit); BOOST_TEST(pi.full); pi = parse("whatdahell", rev2 = anychar_p[rev2.ch = arg1] >> !rev2 >> f_ch_p(rev2.ch) ); BOOST_TEST(!pi.hit); rule complex_p; complex_p = int_p[bind(&X::a)(complex_p.x) = arg1] >> ',' >> int_p[bind(&X::b)(complex_p.x) = arg1] ; X x; pi = parse("123, 456", complex_p[var(x) = arg1], space_p); BOOST_TEST(pi.hit); BOOST_TEST(x.a == 123); BOOST_TEST(x.b == 456); rule, my_closure5::context_t> init1; // compile check only rule<> r1 = init1(3, 3); // member2 is constructed from int rule, my_closure6::context_t> init2; // compile check only rule<> r2 = init2(3); // member2 and member3 are default constructed } /////////////////////////////////////////////////////////////////////////////// // // Main // /////////////////////////////////////////////////////////////////////////////// int main() { closure_tests(); return boost::report_errors(); }