1 /*=============================================================================
2 Copyright (c) 1998-2003 Joel de Guzman
3 http://spirit.sourceforge.net/
5 Use, modification and distribution is subject to the Boost Software
6 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7 http://www.boost.org/LICENSE_1_0.txt)
8 =============================================================================*/
12 //#define BOOST_SPIRIT_DEBUG
13 #define BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT 3
15 #include <boost/spirit/include/classic_core.hpp>
16 #include <boost/spirit/include/classic_stored_rule.hpp>
18 #include <boost/core/lightweight_test.hpp>
20 using namespace BOOST_SPIRIT_CLASSIC_NS
;
22 ///////////////////////////////////////////////////////////////////////////////
26 ///////////////////////////////////////////////////////////////////////////////
34 std::cout
<< "sizeof(rule<>): " << sizeof(rule
<>) << std::endl
;
36 BOOST_SPIRIT_DEBUG_RULE(a
);
37 BOOST_SPIRIT_DEBUG_RULE(b
);
38 BOOST_SPIRIT_DEBUG_RULE(c
);
41 BOOST_SPIRIT_DEBUG_RULE(start
);
44 d
= start
; // aliasing
46 parse_info
<char const*> pi
;
49 pi
= parse("abcabcacb", d
);
52 BOOST_TEST(pi
.length
== 9);
53 BOOST_TEST(*pi
.stop
== 0);
55 start
= (a
| b
) >> (start
| b
);
56 pi
= parse("aaaabababaaabbb", d
);
59 BOOST_TEST(pi
.length
== 15);
60 BOOST_TEST(*pi
.stop
== 0);
64 rule_template_param_tests()
66 // test that rules can be issued its template params in any order:
70 rule
<scanner
<>, parser_context
<> > rx3
;
71 rule
<scanner
<>, parser_context
<>, parser_address_tag
> rx4
;
73 rule
<parser_context
<> > rx5
;
74 rule
<parser_context
<>, parser_address_tag
> rx6
;
75 rule
<parser_context
<>, parser_address_tag
, scanner
<> > rx7
;
77 rule
<parser_address_tag
> rx8
;
78 rule
<parser_address_tag
, scanner
<> > rx9
;
79 rule
<parser_address_tag
, scanner
<>, parser_context
<> > rx10
;
81 rule
<parser_address_tag
, parser_context
<> > rx11
;
82 rule
<parser_address_tag
, parser_context
<>, scanner
<> > rx12
;
84 rule
<parser_context
<>, scanner
<> > rx13
;
85 rule
<parser_context
<>, scanner
<>, parser_address_tag
> rx14
;
88 struct my_grammar
: public grammar
<my_grammar
>
90 template <typename ScannerT
>
93 definition(my_grammar
const& /*self*/)
96 rr
= +(lexeme_d
[r
] >> as_lower_d
[r
] >> r
);
101 , typename lexeme_scanner
<ScannerT
>::type
102 , typename as_lower_scanner
<ScannerT
>::type
107 rule
<ScannerT
> const& start() const { return rr
; }
112 rule_2_or_more_scanners_tests()
115 typedef scanner_list
<scanner
<>, phrase_scanner_t
> scanners
;
117 rule
<scanners
> r
= +anychar_p
;
118 BOOST_TEST(parse("abcdefghijk", r
).full
);
119 BOOST_TEST(parse("a b c d e f g h i j k", r
, space_p
).full
);
124 BOOST_TEST(parse("abcdef aBc d e f aBc d E f", g
, space_p
).full
);
131 rule
<> a
= ch_p('a');
132 rule
<> b
= ch_p('b');
133 rule
<> c
= ch_p('c');
135 BOOST_SPIRIT_DEBUG_RULE(a
);
136 BOOST_SPIRIT_DEBUG_RULE(b
);
137 BOOST_SPIRIT_DEBUG_RULE(c
);
139 parse_info
<char const*> pi
;
141 rule
<> start
= *(a
| b
| c
);
143 BOOST_SPIRIT_DEBUG_RULE(start
);
145 pi
= parse("abcabcacb", start
);
148 BOOST_TEST(pi
.length
== 9);
149 BOOST_TEST(*pi
.stop
== 0);
151 start
= (a
| b
) >> (start
| b
);
152 pi
= parse("aaaabababaaabbb", start
);
155 BOOST_TEST(pi
.length
== 15);
156 BOOST_TEST(*pi
.stop
== 0);
158 pi
= parse("aaaabababaaabba", start
);
160 BOOST_TEST(!pi
.full
);
161 BOOST_TEST(pi
.length
== 14);
163 rule
<> r
= anychar_p
;
164 r
.copy(); // copy test (compile only)
168 stored_rule_basic_tests()
170 stored_rule
<> a
= ch_p('a');
171 stored_rule
<> b
= ch_p('b');
172 stored_rule
<> c
= ch_p('c');
174 BOOST_SPIRIT_DEBUG_RULE(a
);
175 BOOST_SPIRIT_DEBUG_RULE(b
);
176 BOOST_SPIRIT_DEBUG_RULE(c
);
178 parse_info
<char const*> pi
;
180 stored_rule
<> start
= *(a
| b
| c
);
182 BOOST_SPIRIT_DEBUG_RULE(start
);
184 pi
= parse("abcabcacb", start
);
187 BOOST_TEST(pi
.length
== 9);
188 BOOST_TEST(*pi
.stop
== 0);
190 start
= (a
| b
) >> (start
| b
);
191 pi
= parse("aaaabababaaabbb", start
);
194 BOOST_TEST(pi
.length
== 15);
195 BOOST_TEST(*pi
.stop
== 0);
197 pi
= parse("aaaabababaaabba", start
);
199 BOOST_TEST(!pi
.full
);
200 BOOST_TEST(pi
.length
== 14);
204 stored_rule_dynamic_tests()
206 rule
<> a
= ch_p('a');
207 rule
<> b
= ch_p('b');
208 rule
<> c
= ch_p('c');
210 BOOST_SPIRIT_DEBUG_RULE(a
);
211 BOOST_SPIRIT_DEBUG_RULE(b
);
212 BOOST_SPIRIT_DEBUG_RULE(c
);
214 parse_info
<char const*> pi
;
216 // The FF is the dynamic equivalent of start = *(a | b | c);
217 stored_rule
<> start
= a
;
218 start
= start
.copy() | b
;
219 start
= start
.copy() | c
;
220 start
= *(start
.copy());
222 std::cout
<< "sizeof(stored_rule<>): " << sizeof(stored_rule
<>) << std::endl
;
224 BOOST_SPIRIT_DEBUG_RULE(start
);
226 pi
= parse("abcabcacb", start
);
229 BOOST_TEST(pi
.length
== 9);
230 BOOST_TEST(*pi
.stop
== 0);
232 // The FF is the dynamic equivalent of start = (a | b) >> (start | b);
234 start
= a
| start
.copy();
235 start
= start
.copy() >> (start
| b
);
237 pi
= parse("aaaabababaaabbb", start
);
240 BOOST_TEST(pi
.length
== 15);
241 BOOST_TEST(*pi
.stop
== 0);
243 pi
= parse("aaaabababaaabba", start
);
245 BOOST_TEST(!pi
.full
);
246 BOOST_TEST(pi
.length
== 14);
249 ///////////////////////////////////////////////////////////////////////////////
253 ///////////////////////////////////////////////////////////////////////////////
259 rule_template_param_tests();
260 rule_2_or_more_scanners_tests();
261 stored_rule_basic_tests();
262 stored_rule_dynamic_tests();
264 return boost::report_errors();