rule_tests.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. /*=============================================================================
  2. Copyright (c) 1998-2003 Joel de Guzman
  3. http://spirit.sourceforge.net/
  4. Use, modification and distribution is subject to the Boost Software
  5. License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  6. http://www.boost.org/LICENSE_1_0.txt)
  7. =============================================================================*/
  8. #include <iostream>
  9. #include <boost/detail/lightweight_test.hpp>
  10. //#define BOOST_SPIRIT_DEBUG
  11. #define BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT 3
  12. #include <boost/spirit/include/classic_core.hpp>
  13. #include <boost/spirit/include/classic_stored_rule.hpp>
  14. using namespace BOOST_SPIRIT_CLASSIC_NS;
  15. ///////////////////////////////////////////////////////////////////////////////
  16. //
  17. // Rule tests
  18. //
  19. ///////////////////////////////////////////////////////////////////////////////
  20. void
  21. aliasing_tests()
  22. {
  23. rule<> a = ch_p('a');
  24. rule<> b = ch_p('b');
  25. rule<> c = ch_p('c');
  26. std::cout << "sizeof(rule<>): " << sizeof(rule<>) << std::endl;
  27. BOOST_SPIRIT_DEBUG_RULE(a);
  28. BOOST_SPIRIT_DEBUG_RULE(b);
  29. BOOST_SPIRIT_DEBUG_RULE(c);
  30. rule<> start;
  31. BOOST_SPIRIT_DEBUG_RULE(start);
  32. rule<> d;
  33. d = start; // aliasing
  34. parse_info<char const*> pi;
  35. start = *(a | b | c);
  36. pi = parse("abcabcacb", d);
  37. BOOST_TEST(pi.hit);
  38. BOOST_TEST(pi.full);
  39. BOOST_TEST(pi.length == 9);
  40. BOOST_TEST(*pi.stop == 0);
  41. start = (a | b) >> (start | b);
  42. pi = parse("aaaabababaaabbb", d);
  43. BOOST_TEST(pi.hit);
  44. BOOST_TEST(pi.full);
  45. BOOST_TEST(pi.length == 15);
  46. BOOST_TEST(*pi.stop == 0);
  47. }
  48. void
  49. rule_template_param_tests()
  50. {
  51. // test that rules can be issued its template params in any order:
  52. rule<> rx1;
  53. rule<scanner<> > rx2;
  54. rule<scanner<>, parser_context<> > rx3;
  55. rule<scanner<>, parser_context<>, parser_address_tag> rx4;
  56. rule<parser_context<> > rx5;
  57. rule<parser_context<>, parser_address_tag> rx6;
  58. rule<parser_context<>, parser_address_tag, scanner<> > rx7;
  59. rule<parser_address_tag> rx8;
  60. rule<parser_address_tag, scanner<> > rx9;
  61. rule<parser_address_tag, scanner<>, parser_context<> > rx10;
  62. rule<parser_address_tag, parser_context<> > rx11;
  63. rule<parser_address_tag, parser_context<>, scanner<> > rx12;
  64. rule<parser_context<>, scanner<> > rx13;
  65. rule<parser_context<>, scanner<>, parser_address_tag> rx14;
  66. }
  67. struct my_grammar : public grammar<my_grammar>
  68. {
  69. template <typename ScannerT>
  70. struct definition
  71. {
  72. definition(my_grammar const& /*self*/)
  73. {
  74. r = lower_p;
  75. rr = +(lexeme_d[r] >> as_lower_d[r] >> r);
  76. }
  77. typedef scanner_list<
  78. ScannerT
  79. , typename lexeme_scanner<ScannerT>::type
  80. , typename as_lower_scanner<ScannerT>::type
  81. > scanners;
  82. rule<scanners> r;
  83. rule<ScannerT> rr;
  84. rule<ScannerT> const& start() const { return rr; }
  85. };
  86. };
  87. void
  88. rule_2_or_more_scanners_tests()
  89. {
  90. { // 2 scanners
  91. typedef scanner_list<scanner<>, phrase_scanner_t> scanners;
  92. rule<scanners> r = +anychar_p;
  93. BOOST_TEST(parse("abcdefghijk", r).full);
  94. BOOST_TEST(parse("a b c d e f g h i j k", r, space_p).full);
  95. }
  96. { // 3 scanners
  97. my_grammar g;
  98. BOOST_TEST(parse("abcdef aBc d e f aBc d E f", g, space_p).full);
  99. }
  100. }
  101. void
  102. rule_basic_tests()
  103. {
  104. rule<> a = ch_p('a');
  105. rule<> b = ch_p('b');
  106. rule<> c = ch_p('c');
  107. BOOST_SPIRIT_DEBUG_RULE(a);
  108. BOOST_SPIRIT_DEBUG_RULE(b);
  109. BOOST_SPIRIT_DEBUG_RULE(c);
  110. parse_info<char const*> pi;
  111. rule<> start = *(a | b | c);
  112. BOOST_SPIRIT_DEBUG_RULE(start);
  113. pi = parse("abcabcacb", start);
  114. BOOST_TEST(pi.hit);
  115. BOOST_TEST(pi.full);
  116. BOOST_TEST(pi.length == 9);
  117. BOOST_TEST(*pi.stop == 0);
  118. start = (a | b) >> (start | b);
  119. pi = parse("aaaabababaaabbb", start);
  120. BOOST_TEST(pi.hit);
  121. BOOST_TEST(pi.full);
  122. BOOST_TEST(pi.length == 15);
  123. BOOST_TEST(*pi.stop == 0);
  124. pi = parse("aaaabababaaabba", start);
  125. BOOST_TEST(pi.hit);
  126. BOOST_TEST(!pi.full);
  127. BOOST_TEST(pi.length == 14);
  128. rule<> r = anychar_p;
  129. r.copy(); // copy test (compile only)
  130. }
  131. void
  132. stored_rule_basic_tests()
  133. {
  134. stored_rule<> a = ch_p('a');
  135. stored_rule<> b = ch_p('b');
  136. stored_rule<> c = ch_p('c');
  137. BOOST_SPIRIT_DEBUG_RULE(a);
  138. BOOST_SPIRIT_DEBUG_RULE(b);
  139. BOOST_SPIRIT_DEBUG_RULE(c);
  140. parse_info<char const*> pi;
  141. stored_rule<> start = *(a | b | c);
  142. BOOST_SPIRIT_DEBUG_RULE(start);
  143. pi = parse("abcabcacb", start);
  144. BOOST_TEST(pi.hit);
  145. BOOST_TEST(pi.full);
  146. BOOST_TEST(pi.length == 9);
  147. BOOST_TEST(*pi.stop == 0);
  148. start = (a | b) >> (start | b);
  149. pi = parse("aaaabababaaabbb", start);
  150. BOOST_TEST(pi.hit);
  151. BOOST_TEST(pi.full);
  152. BOOST_TEST(pi.length == 15);
  153. BOOST_TEST(*pi.stop == 0);
  154. pi = parse("aaaabababaaabba", start);
  155. BOOST_TEST(pi.hit);
  156. BOOST_TEST(!pi.full);
  157. BOOST_TEST(pi.length == 14);
  158. }
  159. void
  160. stored_rule_dynamic_tests()
  161. {
  162. rule<> a = ch_p('a');
  163. rule<> b = ch_p('b');
  164. rule<> c = ch_p('c');
  165. BOOST_SPIRIT_DEBUG_RULE(a);
  166. BOOST_SPIRIT_DEBUG_RULE(b);
  167. BOOST_SPIRIT_DEBUG_RULE(c);
  168. parse_info<char const*> pi;
  169. // The FF is the dynamic equivalent of start = *(a | b | c);
  170. stored_rule<> start = a;
  171. start = start.copy() | b;
  172. start = start.copy() | c;
  173. start = *(start.copy());
  174. std::cout << "sizeof(stored_rule<>): " << sizeof(stored_rule<>) << std::endl;
  175. BOOST_SPIRIT_DEBUG_RULE(start);
  176. pi = parse("abcabcacb", start);
  177. BOOST_TEST(pi.hit);
  178. BOOST_TEST(pi.full);
  179. BOOST_TEST(pi.length == 9);
  180. BOOST_TEST(*pi.stop == 0);
  181. // The FF is the dynamic equivalent of start = (a | b) >> (start | b);
  182. start = b;
  183. start = a | start.copy();
  184. start = start.copy() >> (start | b);
  185. pi = parse("aaaabababaaabbb", start);
  186. BOOST_TEST(pi.hit);
  187. BOOST_TEST(pi.full);
  188. BOOST_TEST(pi.length == 15);
  189. BOOST_TEST(*pi.stop == 0);
  190. pi = parse("aaaabababaaabba", start);
  191. BOOST_TEST(pi.hit);
  192. BOOST_TEST(!pi.full);
  193. BOOST_TEST(pi.length == 14);
  194. }
  195. ///////////////////////////////////////////////////////////////////////////////
  196. //
  197. // Main
  198. //
  199. ///////////////////////////////////////////////////////////////////////////////
  200. int
  201. main()
  202. {
  203. rule_basic_tests();
  204. aliasing_tests();
  205. rule_template_param_tests();
  206. rule_2_or_more_scanners_tests();
  207. stored_rule_basic_tests();
  208. stored_rule_dynamic_tests();
  209. return boost::report_errors();
  210. }