1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
/*=============================================================================
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 <iostream>
#include <boost/spirit/include/classic_core.hpp>
#include <boost/spirit/include/classic_closure.hpp>
#include <boost/spirit/include/classic_parametric.hpp>
#include <boost/spirit/include/phoenix1_binders.hpp>
#include <boost/core/lightweight_test.hpp>
using namespace BOOST_SPIRIT_CLASSIC_NS;
using namespace phoenix;
///////////////////////////////////////////////////////////////////////////////
//
// Closure tests
//
///////////////////////////////////////////////////////////////////////////////
struct my_closure1 : BOOST_SPIRIT_CLASSIC_NS::closure<my_closure1, double>
{
member1 val;
};
struct my_closure2 : BOOST_SPIRIT_CLASSIC_NS::closure<my_closure2, char>
{
member1 ch;
};
struct my_closure3 : BOOST_SPIRIT_CLASSIC_NS::closure<my_closure3, char>
{
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<my_closure4, X>
{
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<my_closure5, int, Y>
{
member1 y;
};
struct my_closure6 : BOOST_SPIRIT_CLASSIC_NS::closure<my_closure6, int, int, int>
{
member1 x;
member2 y;
member3 z;
};
void
closure_tests()
{
rule<phrase_scanner_t, my_closure1::context_t> 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<char const*> 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<scanner<>, 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<phrase_scanner_t, my_closure4::context_t> 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<scanner<>, my_closure5::context_t> init1; // compile check only
rule<> r1 = init1(3, 3); // member2 is constructed from int
rule<scanner<>, 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();
}
|