if_tests.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. /*=============================================================================
  2. Copyright (c) 2004 Stefan Slapeta
  3. Copyright (c) 2002-2003 Martin Wille
  4. 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. =============================================================================*/
  9. // vi:ts=4:sw=4:et
  10. // Tests for BOOST_SPIRIT_CLASSIC_NS::if_p
  11. // [28-Dec-2002]
  12. ////////////////////////////////////////////////////////////////////////////////
  13. #include <iostream>
  14. #include <cstring>
  15. #include <boost/spirit/include/classic_core.hpp>
  16. #include <boost/spirit/include/classic_if.hpp>
  17. #include <boost/spirit/include/classic_assign_actor.hpp>
  18. #include <boost/ref.hpp>
  19. #include "impl/string_length.hpp"
  20. namespace local
  21. {
  22. template <typename T>
  23. struct var_wrapper
  24. : public ::boost::reference_wrapper<T>
  25. {
  26. typedef ::boost::reference_wrapper<T> parent;
  27. explicit inline var_wrapper(T& t) : parent(t) {}
  28. inline T& operator()() const { return parent::get(); }
  29. };
  30. template <typename T>
  31. inline var_wrapper<T>
  32. var(T& t)
  33. {
  34. return var_wrapper<T>(t);
  35. }
  36. }
  37. typedef ::BOOST_SPIRIT_CLASSIC_NS::rule<> rule_t;
  38. typedef ::BOOST_SPIRIT_CLASSIC_NS::rule<BOOST_SPIRIT_CLASSIC_NS::no_actions_scanner<>::type >
  39. no_actions_rule_t;
  40. unsigned int test_count = 0;
  41. unsigned int error_count = 0;
  42. unsigned int number_result;
  43. static const unsigned int kError = 999;
  44. static const bool good = true;
  45. static const bool bad = false;
  46. rule_t hex_prefix;
  47. no_actions_rule_t oct_prefix;
  48. rule_t hex_rule, oct_rule, dec_rule;
  49. rule_t auto_number_rule;
  50. rule_t hex_or_dec_number_rule;
  51. void
  52. test_number(char const *s, unsigned int wanted, rule_t const &r)
  53. {
  54. using namespace std;
  55. ++test_count;
  56. number_result = wanted-1;
  57. ::BOOST_SPIRIT_CLASSIC_NS::parse_info<> m = ::BOOST_SPIRIT_CLASSIC_NS::parse(s, s + test_impl::string_length(s), r);
  58. bool result = wanted == kError?(m.full?bad:good): (number_result==wanted);
  59. if (m.full && (m.length != test_impl::string_length(s)))
  60. result = bad;
  61. if (result==good)
  62. cout << "PASSED";
  63. else
  64. {
  65. ++error_count;
  66. cout << "FAILED";
  67. }
  68. cout << ": \"" << s << "\" ==> ";
  69. if (number_result==wanted-1)
  70. cout << "<error>";
  71. else
  72. cout << number_result;
  73. cout << "\n";
  74. }
  75. void
  76. test_enclosed_fail()
  77. {
  78. using namespace std;
  79. using ::BOOST_SPIRIT_CLASSIC_NS::if_p;
  80. using ::BOOST_SPIRIT_CLASSIC_NS::str_p;
  81. using ::BOOST_SPIRIT_CLASSIC_NS::nothing_p;
  82. cout << "\nfail enclosed parser:\n";
  83. const char *p = "abc";
  84. ::BOOST_SPIRIT_CLASSIC_NS::strlit<const char*> success_p = str_p(p);
  85. ::BOOST_SPIRIT_CLASSIC_NS::strlit<const char*> fail_p = str_p("xxx");
  86. ::BOOST_SPIRIT_CLASSIC_NS::rule<> r = if_p(success_p)[nothing_p];
  87. ::BOOST_SPIRIT_CLASSIC_NS::parse_info<> m = ::BOOST_SPIRIT_CLASSIC_NS::parse(p, r);
  88. if (m.full) {
  89. cout << "FAILED: if --> match" << endl;
  90. ++error_count;
  91. } else {
  92. cout << "PASSED: if --> no_match" << endl;
  93. }
  94. r = if_p(fail_p)[success_p].else_p[nothing_p];
  95. m = ::BOOST_SPIRIT_CLASSIC_NS::parse(p, r);
  96. if (m.full) {
  97. cout << "FAILED: else --> match" << endl;
  98. ++error_count;
  99. } else {
  100. cout << "PASSED: else --> no_match" << endl;
  101. }
  102. }
  103. int
  104. main()
  105. {
  106. using namespace std;
  107. using ::BOOST_SPIRIT_CLASSIC_NS::if_p;
  108. using ::BOOST_SPIRIT_CLASSIC_NS::uint_p;
  109. using ::BOOST_SPIRIT_CLASSIC_NS::oct_p;
  110. using ::BOOST_SPIRIT_CLASSIC_NS::hex_p;
  111. using ::BOOST_SPIRIT_CLASSIC_NS::str_p;
  112. using ::BOOST_SPIRIT_CLASSIC_NS::ch_p;
  113. using ::BOOST_SPIRIT_CLASSIC_NS::assign_a;
  114. cout << "/////////////////////////////////////////////////////////\n";
  115. cout << "\n";
  116. cout << " if_p test\n";
  117. cout << "\n";
  118. cout << "/////////////////////////////////////////////////////////\n";
  119. cout << "\n";
  120. bool as_hex;
  121. #if qDebug
  122. BOOST_SPIRIT_DEBUG_RULE(hex_prefix);
  123. BOOST_SPIRIT_DEBUG_RULE(hex_rule);
  124. BOOST_SPIRIT_DEBUG_RULE(oct_prefix);
  125. BOOST_SPIRIT_DEBUG_RULE(oct_rule);
  126. BOOST_SPIRIT_DEBUG_RULE(dec_rule);
  127. BOOST_SPIRIT_DEBUG_RULE(auto_number_rule);
  128. BOOST_SPIRIT_DEBUG_RULE(hex_or_dec_number_rule);
  129. #endif
  130. hex_prefix = str_p("0x");
  131. oct_prefix = ch_p('0');
  132. hex_rule = hex_p[assign_a(number_result)];
  133. oct_rule = oct_p[assign_a(number_result)];
  134. dec_rule = uint_p[assign_a(number_result)];
  135. auto_number_rule =
  136. if_p(hex_prefix)
  137. [hex_rule]
  138. .else_p
  139. [
  140. if_p(::BOOST_SPIRIT_CLASSIC_NS::eps_p(oct_prefix))
  141. [oct_rule]
  142. .else_p
  143. [dec_rule]
  144. ];
  145. hex_or_dec_number_rule =
  146. if_p(local::var(as_hex))[hex_prefix>>hex_rule].else_p[dec_rule];
  147. cout << "auto:\n";
  148. test_number("", kError, auto_number_rule);
  149. test_number("0", 0, auto_number_rule);
  150. test_number("1", 1, auto_number_rule);
  151. test_number("00", 0, auto_number_rule);
  152. test_number("0x", kError, auto_number_rule);
  153. test_number("0x0", 0, auto_number_rule);
  154. test_number("0755", 493, auto_number_rule);
  155. test_number("0x100", 256, auto_number_rule);
  156. cout << "\ndecimal:\n";
  157. as_hex = false;
  158. test_number("", kError, hex_or_dec_number_rule);
  159. test_number("100", 100, hex_or_dec_number_rule);
  160. test_number("0x100", kError, hex_or_dec_number_rule);
  161. test_number("0xff", kError, hex_or_dec_number_rule);
  162. cout << "\nhexadecimal:\n";
  163. as_hex = true;
  164. test_number("", kError, hex_or_dec_number_rule);
  165. test_number("0x100", 256, hex_or_dec_number_rule);
  166. test_number("0xff", 255, hex_or_dec_number_rule);
  167. //////////////////////////////////
  168. // tests for if_p without else-parser
  169. cout << "\nno-else:\n";
  170. rule_t r = if_p(::BOOST_SPIRIT_CLASSIC_NS::eps_p('0'))[oct_rule];
  171. test_number("0", 0, r);
  172. ++test_count;
  173. ::BOOST_SPIRIT_CLASSIC_NS::parse_info<> m = ::BOOST_SPIRIT_CLASSIC_NS::parse("", r);
  174. if (!m.hit || !m.full || m.length!=0)
  175. {
  176. std::cout << "FAILED: \"\" ==> <error>\n";
  177. ++error_count;
  178. }
  179. else
  180. std::cout << "PASSED: \"\" ==> <empty match>\n";
  181. ++test_count;
  182. m = ::BOOST_SPIRIT_CLASSIC_NS::parse("junk", r);
  183. if (!m.hit || m.full || m.length!=0)
  184. {
  185. std::cout << "FAILED: \"junk\" ==> <error>\n";
  186. ++error_count;
  187. }
  188. else
  189. std::cout << "PASSED: \"junk\" ==> <empty match>\n";
  190. test_enclosed_fail();
  191. //////////////////////////////////
  192. // report results
  193. std::cout << "\n ";
  194. if (error_count==0)
  195. cout << "All " << test_count << " if_p-tests passed.\n"
  196. << "Test concluded successfully\n";
  197. else
  198. cout << error_count << " of " << test_count << " if_p-tests failed\n"
  199. << "Test failed\n";
  200. return error_count!=0;
  201. }