1///////////////////////////////////////////////////////////////////////////////
2// misc1.hpp
3//
4// Copyright 2008 Eric Niebler. Distributed under the Boost
5// Software License, Version 1.0. (See accompanying file
6// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7
8#include <iostream>
9#include <boost/xpressive/xpressive.hpp>
10#include <boost/xpressive/traits/cpp_regex_traits.hpp>
11#include <boost/test/unit_test.hpp>
12
13using namespace boost::unit_test;
14using namespace boost::xpressive;
15
16void test1()
17{
18 // make sure the following compiles:
19 sregex a = _;
20 sregex b = _;
21 sregex c = a >> b;
22 c = 'a' >> b;
23 c = a >> 'b';
24 c = a | b;
25 c = 'a' | b;
26 c = a | 'b';
27 c = !a;
28 c = *a;
29 c = +a;
30}
31
32///////////////////////////////////////////////////////////////////////////////
33// test for basic_regex in a keep
34//
35void test2()
36{
37 std::locale loc;
38 std::string str("Its a mad Mad mAd maD world");
39 sregex word = +_w;
40 sregex sentence = imbue(loc)(*(keep(expr: word) >> +_s) >> word);
41 smatch what;
42
43 BOOST_REQUIRE(regex_match(str, what, sentence));
44 BOOST_REQUIRE(7 == what.nested_results().size());
45 smatch::nested_results_type::const_iterator pword = what.nested_results().begin();
46 BOOST_CHECK((*pword++)[0] == "Its");
47 BOOST_CHECK((*pword++)[0] == "a");
48 BOOST_CHECK((*pword++)[0] == "mad");
49 BOOST_CHECK((*pword++)[0] == "Mad");
50 BOOST_CHECK((*pword++)[0] == "mAd");
51 BOOST_CHECK((*pword++)[0] == "maD");
52 BOOST_CHECK((*pword++)[0] == "world");
53 BOOST_CHECK(pword == what.nested_results().end());
54}
55
56///////////////////////////////////////////////////////////////////////////////
57// test for a simple non-recursive grammar
58//
59void test3()
60{
61 // test for a simple regex grammar
62 std::string buffer =
63 "FROGGIE\r\n"
64 "Volume = 1\r\n"
65 "Other1= 2\r\n"
66 "Channel=3\r\n"
67 "Other =4\r\n"
68 "\r\n"
69 "FROGGIE\r\n"
70 "Volume = 5\r\n"
71 "Other1= 6\r\n"
72 "Channel=7\r\n"
73 "Other =8\r\n"
74 "\r\n"
75 "FROGGIE\r\n"
76 "Volume = 9\r\n"
77 "Other1= 0\r\n"
78 "Channel=10\r\n"
79 "\r\n";
80
81 mark_tag name(1), value(2);
82
83 sregex name_value_pair_ =
84 (name= +alnum) >> *_s >> "=" >> *_s >>
85 (value= +_d) >> *_s >> _ln;
86
87 sregex message_ =
88 *_s >> "FROGGIE" >> _ln >> +name_value_pair_ >> _ln;
89
90 sregex re_ = +message_;
91
92 smatch::nested_results_type::const_iterator msg, nvp;
93 smatch tmpwhat;
94
95 BOOST_REQUIRE(regex_search(buffer, tmpwhat, re_));
96 // for giggles, make a deep-copy of the tree of results
97 smatch what = tmpwhat;
98 BOOST_REQUIRE(3 == what.nested_results().size());
99
100 msg = what.nested_results().begin();
101 BOOST_REQUIRE(4 == msg->nested_results().size());
102
103 nvp = msg->nested_results().begin();
104 BOOST_REQUIRE(3 == nvp->size());
105 BOOST_CHECK("Volume" == (*nvp)[name]);
106 BOOST_CHECK("1" == (*nvp)[value]);
107 ++nvp;
108 BOOST_REQUIRE(3 == nvp->size());
109 BOOST_CHECK("Other1" == (*nvp)[name]);
110 BOOST_CHECK("2" == (*nvp)[value]);
111 ++nvp;
112 BOOST_REQUIRE(3 == nvp->size());
113 BOOST_CHECK("Channel" == (*nvp)[name]);
114 BOOST_CHECK("3" == (*nvp)[value]);
115 ++nvp;
116 BOOST_REQUIRE(3 == nvp->size());
117 BOOST_CHECK("Other" == (*nvp)[name]);
118 BOOST_CHECK("4" == (*nvp)[value]);
119
120 ++msg;
121 BOOST_REQUIRE(4 == msg->nested_results().size());
122
123 nvp = msg->nested_results().begin();
124 BOOST_REQUIRE(3 == nvp->size());
125 BOOST_CHECK("Volume" == (*nvp)[name]);
126 BOOST_CHECK("5" == (*nvp)[value]);
127 ++nvp;
128 BOOST_REQUIRE(3 == nvp->size());
129 BOOST_CHECK("Other1" == (*nvp)[name]);
130 BOOST_CHECK("6" == (*nvp)[value]);
131 ++nvp;
132 BOOST_REQUIRE(3 == nvp->size());
133 BOOST_CHECK("Channel" == (*nvp)[name]);
134 BOOST_CHECK("7" == (*nvp)[value]);
135 ++nvp;
136 BOOST_REQUIRE(3 == nvp->size());
137 BOOST_CHECK("Other" == (*nvp)[name]);
138 BOOST_CHECK("8" == (*nvp)[value]);
139
140 ++msg;
141 BOOST_REQUIRE(3 == msg->nested_results().size());
142
143 nvp = msg->nested_results().begin();
144 BOOST_REQUIRE(3 == nvp->size());
145 BOOST_CHECK("Volume" == (*nvp)[name]);
146 BOOST_CHECK("9" == (*nvp)[value]);
147 ++nvp;
148 BOOST_REQUIRE(3 == nvp->size());
149 BOOST_CHECK("Other1" == (*nvp)[name]);
150 BOOST_CHECK("0" == (*nvp)[value]);
151 ++nvp;
152 BOOST_REQUIRE(3 == nvp->size());
153 BOOST_CHECK("Channel" == (*nvp)[name]);
154 BOOST_CHECK("10" == (*nvp)[value]);
155}
156
157///////////////////////////////////////////////////////////////////////////////
158// test for a self-recursive regex
159//
160void test4()
161{
162 sregex parentheses;
163 parentheses // A balanced set of parentheses ...
164 = '(' // is an opening parenthesis ...
165 >> // followed by ...
166 *( // zero or more ...
167 keep( expr: +~(set='(',')') ) // of a bunch of things that are not parentheses ...
168 | // or ...
169 by_ref(rex: parentheses) // a balanced set of parentheses
170 ) // (ooh, recursion!) ...
171 >> // followed by ...
172 ')' // a closing parenthesis
173 ;
174
175 smatch what;
176 smatch::nested_results_type::const_iterator pwhat, pwhat2;
177 std::string str( "blah blah( a(b)c (c(e)f (g)h )i (j)6 )blah" );
178
179 BOOST_REQUIRE(regex_search(str, what, parentheses));
180 BOOST_REQUIRE(1 == what.size());
181 BOOST_CHECK("( a(b)c (c(e)f (g)h )i (j)6 )" == what[0]);
182
183 BOOST_REQUIRE(3 == what.nested_results().size());
184 pwhat = what.nested_results().begin();
185 BOOST_REQUIRE(1 == pwhat->size());
186 BOOST_CHECK("(b)" == (*pwhat)[0]);
187
188 ++pwhat;
189 BOOST_REQUIRE(1 == pwhat->size());
190 BOOST_CHECK("(c(e)f (g)h )" == (*pwhat)[0]);
191
192 BOOST_REQUIRE(2 == pwhat->nested_results().size());
193 pwhat2 = pwhat->nested_results().begin();
194 BOOST_REQUIRE(1 == pwhat2->size());
195 BOOST_CHECK("(e)" == (*pwhat2)[0]);
196
197 ++pwhat2;
198 BOOST_REQUIRE(1 == pwhat2->size());
199 BOOST_CHECK("(g)" == (*pwhat2)[0]);
200
201 ++pwhat;
202 BOOST_REQUIRE(1 == pwhat->size());
203 BOOST_CHECK("(j)" == (*pwhat)[0]);
204}
205
206///////////////////////////////////////////////////////////////////////////////
207// test for a sub-match scoping
208//
209void test5()
210{
211 sregex inner = sregex::compile( begin: "(.)\\1" );
212 sregex outer = (s1= _) >> inner >> s1;
213 std::string abba("ABBA");
214
215 BOOST_CHECK(regex_match(abba, outer));
216}
217
218///////////////////////////////////////////////////////////////////////////////
219// Ye olde calculator. Test recursive grammar.
220//
221void test6()
222{
223 sregex group, factor, term, expression;
224
225 group = '(' >> by_ref(rex: expression) >> ')';
226 factor = +_d | group;
227 term = factor >> *(('*' >> factor) | ('/' >> factor));
228 expression = term >> *(('+' >> term) | ('-' >> term));
229
230 smatch what;
231 std::string str("foo 9*(10+3) bar");
232
233 BOOST_REQUIRE(regex_search(str, what, expression));
234 BOOST_CHECK("9*(10+3)" == what[0]);
235}
236
237///////////////////////////////////////////////////////////////////////////////
238// init_unit_test_suite
239//
240test_suite* init_unit_test_suite( int argc, char* argv[] )
241{
242 test_suite *test = BOOST_TEST_SUITE("miscelaneous tests and examples from the docs");
243
244 test->add(BOOST_TEST_CASE(&test1));
245 test->add(BOOST_TEST_CASE(&test2));
246 test->add(BOOST_TEST_CASE(&test3));
247 test->add(BOOST_TEST_CASE(&test4));
248 test->add(BOOST_TEST_CASE(&test5));
249 test->add(BOOST_TEST_CASE(&test6));
250
251 return test;
252}
253

source code of boost/libs/xpressive/test/misc1.cpp