misc1.cpp 7.5 KB

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