closure_tests.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /*=============================================================================
  2. Copyright (c) 2001-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. #include <boost/spirit/include/classic_core.hpp>
  11. #include <boost/spirit/include/classic_closure.hpp>
  12. #include <boost/spirit/include/classic_parametric.hpp>
  13. #include <boost/spirit/include/phoenix1_binders.hpp>
  14. using namespace BOOST_SPIRIT_CLASSIC_NS;
  15. using namespace phoenix;
  16. ///////////////////////////////////////////////////////////////////////////////
  17. //
  18. // Closure tests
  19. //
  20. ///////////////////////////////////////////////////////////////////////////////
  21. struct my_closure1 : BOOST_SPIRIT_CLASSIC_NS::closure<my_closure1, double>
  22. {
  23. member1 val;
  24. };
  25. struct my_closure2 : BOOST_SPIRIT_CLASSIC_NS::closure<my_closure2, char>
  26. {
  27. member1 ch;
  28. };
  29. struct my_closure3 : BOOST_SPIRIT_CLASSIC_NS::closure<my_closure3, char>
  30. {
  31. member1 ch;
  32. };
  33. struct X { int a; int b; };
  34. #if defined(BOOST_SPIRIT_DEBUG)
  35. // If debugging is switched on, all closure members should have a
  36. // corresponding output streaming operator
  37. std::ostream &
  38. operator<< (std::ostream& o, X const &x)
  39. {
  40. o << "X(" << x.a << ", " << x.b << ")";
  41. return o;
  42. }
  43. #endif // defined(BOOST_SPIRIT_DEBUG)
  44. struct my_closure4 : BOOST_SPIRIT_CLASSIC_NS::closure<my_closure4, X>
  45. {
  46. member1 x;
  47. };
  48. // MWCW8.3 needs the default constructor here or it won't compile.
  49. // It should not be needed.
  50. struct Y { Y() {} Y(int) {} };
  51. #if defined(BOOST_SPIRIT_DEBUG)
  52. // If debugging is switched on, all closure members should have a
  53. // corresponding output streaming operator
  54. std::ostream &
  55. operator<< (std::ostream& o, Y const &/*x*/)
  56. {
  57. o << "Y";
  58. return o;
  59. }
  60. #endif // defined(BOOST_SPIRIT_DEBUG)
  61. struct my_closure5 : BOOST_SPIRIT_CLASSIC_NS::closure<my_closure5, int, Y>
  62. {
  63. member1 y;
  64. };
  65. struct my_closure6 : BOOST_SPIRIT_CLASSIC_NS::closure<my_closure6, int, int, int>
  66. {
  67. member1 x;
  68. member2 y;
  69. member3 z;
  70. };
  71. void
  72. closure_tests()
  73. {
  74. rule<phrase_scanner_t, my_closure1::context_t> num_list;
  75. double n;
  76. num_list =
  77. (
  78. real_p[num_list.val = arg1] >> *(',' >> real_p[num_list.val += arg1])
  79. )
  80. [var(n) = num_list.val];
  81. parse_info<char const*> pi;
  82. pi = parse("123, 456, 789", num_list, space_p);
  83. BOOST_TEST(pi.hit);
  84. BOOST_TEST(pi.full);
  85. BOOST_TEST(n == 123 + 456 + 789);
  86. rule<scanner<>, my_closure2::context_t> rev;
  87. rev = anychar_p[rev.ch = arg1] >> !rev >> f_ch_p(rev.ch);
  88. pi = parse("xyzzyx", rev);
  89. BOOST_TEST(pi.hit);
  90. BOOST_TEST(pi.full);
  91. pi = parse("xyzczyx", rev);
  92. BOOST_TEST(!pi.hit);
  93. subrule<0, my_closure3::context_t> rev2;
  94. pi = parse("atoyyota",
  95. rev2 = anychar_p[rev2.ch = arg1] >> !rev2 >> f_ch_p(rev2.ch)
  96. );
  97. BOOST_TEST(pi.hit);
  98. BOOST_TEST(pi.full);
  99. pi = parse("whatdahell",
  100. rev2 = anychar_p[rev2.ch = arg1] >> !rev2 >> f_ch_p(rev2.ch)
  101. );
  102. BOOST_TEST(!pi.hit);
  103. rule<phrase_scanner_t, my_closure4::context_t> complex_p;
  104. complex_p =
  105. int_p[bind(&X::a)(complex_p.x) = arg1]
  106. >> ','
  107. >> int_p[bind(&X::b)(complex_p.x) = arg1]
  108. ;
  109. X x;
  110. pi = parse("123, 456", complex_p[var(x) = arg1], space_p);
  111. BOOST_TEST(pi.hit);
  112. BOOST_TEST(x.a == 123);
  113. BOOST_TEST(x.b == 456);
  114. rule<scanner<>, my_closure5::context_t> init1; // compile check only
  115. rule<> r1 = init1(3, 3); // member2 is constructed from int
  116. rule<scanner<>, my_closure6::context_t> init2; // compile check only
  117. rule<> r2 = init2(3); // member2 and member3 are default constructed
  118. }
  119. ///////////////////////////////////////////////////////////////////////////////
  120. //
  121. // Main
  122. //
  123. ///////////////////////////////////////////////////////////////////////////////
  124. int
  125. main()
  126. {
  127. closure_tests();
  128. return boost::report_errors();
  129. }