while_tests.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /*=============================================================================
  2. Phoenix V1.0
  3. Copyright (c) 2002-2003 Martin Wille
  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. // vi:ts=4:sw=4:et
  9. // Tests for BOOST_SPIRIT_CLASSIC_NS::while_p
  10. // [28-Dec-2002]
  11. ////////////////////////////////////////////////////////////////////////////////
  12. #include <iostream>
  13. #include <cstring>
  14. #include "impl/string_length.hpp"
  15. #include <boost/spirit/include/classic_core.hpp>
  16. #include <boost/spirit/include/classic_assign_actor.hpp>
  17. #include <boost/spirit/include/classic_while.hpp>
  18. #include <boost/ref.hpp>
  19. namespace local
  20. {
  21. template <typename T>
  22. struct var_wrapper
  23. : public ::boost::reference_wrapper<T>
  24. {
  25. typedef boost::reference_wrapper<T> parent;
  26. explicit inline var_wrapper(T& t) : parent(t) {}
  27. inline T& operator()() const { return parent::get(); }
  28. };
  29. template <typename T>
  30. inline var_wrapper<T>
  31. var(T& t)
  32. {
  33. return var_wrapper<T>(t);
  34. }
  35. }
  36. namespace
  37. {
  38. template <typename T>
  39. class add_actor
  40. {
  41. public:
  42. explicit add_actor(T &ref_) : ref(ref_) {}
  43. template <typename T2>
  44. void operator()(T2 const &val) const
  45. { ref += val; }
  46. private:
  47. T& ref;
  48. };
  49. template <typename T>
  50. inline add_actor<T> const
  51. add(T& ref)
  52. {
  53. return add_actor<T>(ref);
  54. }
  55. }
  56. typedef BOOST_SPIRIT_CLASSIC_NS::rule<> rule_t;
  57. unsigned int test_count = 0;
  58. unsigned int error_count = 0;
  59. unsigned int iterations_performed;
  60. unsigned int number_result;
  61. static const unsigned int kError = 999;
  62. static const bool good = true;
  63. static const bool bad = false;
  64. rule_t while_rule;
  65. rule_t do_while_rule;
  66. void
  67. test_while(
  68. char const *s,
  69. unsigned int wanted,
  70. rule_t const &r,
  71. unsigned int iterations_wanted)
  72. {
  73. using namespace std;
  74. ++test_count;
  75. number_result = 0;
  76. iterations_performed = 0;
  77. BOOST_SPIRIT_CLASSIC_NS::parse_info<> m = BOOST_SPIRIT_CLASSIC_NS::parse(s, s+ test_impl::string_length(s), r);
  78. bool result = wanted == kError?(m.full?bad:good): (number_result==wanted);
  79. result &= iterations_performed == iterations_wanted;
  80. if (m.full && (m.length != test_impl::string_length(s)))
  81. result = bad;
  82. if (result==good)
  83. cout << "PASSED";
  84. else
  85. {
  86. ++error_count;
  87. cout << "FAILED";
  88. }
  89. cout << ": \"" << s << "\" ==> ";
  90. if (!m.full)
  91. cout << "<error>";
  92. else
  93. cout << number_result;
  94. cout << " " << iterations_performed << " of "
  95. << iterations_wanted << " iterations\n";
  96. }
  97. template<typename T>
  98. struct inc_actor
  99. {
  100. explicit inc_actor(T &t) : var(t) {}
  101. template<typename IteratorT>
  102. void operator()(IteratorT const &, IteratorT const &) const
  103. {
  104. ++var;
  105. }
  106. template<typename U>
  107. void operator()(U) const
  108. {
  109. ++var;
  110. }
  111. T &var;
  112. };
  113. template<typename T>
  114. inc_actor<T>
  115. inc(T &t)
  116. {
  117. return inc_actor<T>(t);
  118. }
  119. int
  120. main()
  121. {
  122. using namespace std;
  123. using ::BOOST_SPIRIT_CLASSIC_NS::uint_p;
  124. using ::BOOST_SPIRIT_CLASSIC_NS::while_p;
  125. using ::BOOST_SPIRIT_CLASSIC_NS::do_p;
  126. using ::BOOST_SPIRIT_CLASSIC_NS::assign_a;
  127. #if qDebug
  128. BOOST_SPIRIT_DEBUG_RULE(while_rule);
  129. BOOST_SPIRIT_DEBUG_RULE(do_while_rule);
  130. #endif
  131. while_rule
  132. = uint_p[assign_a(number_result)]
  133. >> while_p('+')
  134. [
  135. uint_p[add(number_result)][inc(iterations_performed)]
  136. ];
  137. do_while_rule
  138. = do_p
  139. [
  140. uint_p[add(number_result)][inc(iterations_performed)]
  141. ].while_p('+');
  142. cout << "/////////////////////////////////////////////////////////\n";
  143. cout << "\n";
  144. cout << " while_p test\n";
  145. cout << "\n";
  146. cout << "/////////////////////////////////////////////////////////\n";
  147. cout << "\n";
  148. cout << "while_p()[]\n";
  149. test_while("", kError, while_rule, 0);
  150. test_while("1", 1, while_rule, 0);
  151. test_while("1+1", 2, while_rule, 1);
  152. test_while("1+1+12", 14, while_rule, 2);
  153. test_while("1+1+x", kError, while_rule, 1);
  154. cout << "do_p[].while_p()\n";
  155. test_while("", kError, do_while_rule, 0);
  156. test_while("1", 1, do_while_rule, 1);
  157. test_while("1+1", 2, do_while_rule, 2);
  158. test_while("1+1+12", 14, do_while_rule, 3);
  159. test_while("1+1+x", kError, do_while_rule, 2);
  160. std::cout << "\n ";
  161. if (error_count==0)
  162. cout << "All " << test_count << " while_p-tests passed.\n"
  163. << "Test concluded successfully\n";
  164. else
  165. cout << error_count << " of " << test_count << " while_p-tests failed\n"
  166. << "Test failed\n";
  167. return error_count!=0;
  168. }