• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
13 using namespace boost::unit_test;
14 using namespace boost::xpressive;
15 
test1()16 void 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 //
test2()35 void 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(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 //
test3()59 void 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 //
test4()160 void 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( +~(set='(',')') )  // of a bunch of things that are not parentheses ...
168               |                          // or ...
169                 by_ref(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 //
test5()209 void test5()
210 {
211     sregex inner = sregex::compile( "(.)\\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 //
test6()221 void test6()
222 {
223     sregex group, factor, term, expression;
224 
225     group       = '(' >> by_ref(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 //
init_unit_test_suite(int argc,char * argv[])240 test_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