refactoring.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. /*=============================================================================
  2. Copyright (c) 2002-2003 Hartmut Kaiser
  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. ///////////////////////////////////////////////////////////////////////////////
  9. // This example shows the usage of the refactoring parser family parsers
  10. // See the "Refactoring Parsers" chapter in the User's Guide.
  11. #include <iostream>
  12. #include <string>
  13. #include <boost/spirit/include/classic_core.hpp>
  14. #include <boost/spirit/include/classic_refactoring.hpp>
  15. ///////////////////////////////////////////////////////////////////////////////
  16. // used namespaces
  17. using namespace std;
  18. using namespace BOOST_SPIRIT_CLASSIC_NS;
  19. ///////////////////////////////////////////////////////////////////////////////
  20. // actor, used by the refactor_action_p test
  21. struct refactor_action_actor
  22. {
  23. refactor_action_actor (std::string &str_) : str(str_) {}
  24. template <typename IteratorT>
  25. void operator() (IteratorT const &first, IteratorT const &last) const
  26. {
  27. str = std::string(first, last-first);
  28. }
  29. std::string &str;
  30. };
  31. ///////////////////////////////////////////////////////////////////////////////
  32. // main entry point
  33. int main()
  34. {
  35. parse_info<> result;
  36. char const *test_string = "Some string followed by a newline\n";
  37. ///////////////////////////////////////////////////////////////////////////////
  38. //
  39. // 1. Testing the refactor_unary_d parser
  40. //
  41. // The following test should successfully parse the test string, because the
  42. //
  43. // refactor_unary_d[
  44. // *anychar_p - '\n'
  45. // ]
  46. //
  47. // is refactored into
  48. //
  49. // *(anychar_p - '\n').
  50. //
  51. ///////////////////////////////////////////////////////////////////////////////
  52. result = parse(test_string, refactor_unary_d[*anychar_p - '\n'] >> '\n');
  53. if (result.full)
  54. {
  55. cout << "Successfully refactored an unary!" << endl;
  56. }
  57. else
  58. {
  59. cout << "Failed to refactor an unary!" << endl;
  60. }
  61. // Parsing the same test string without refactoring fails, because the
  62. // *anychar_p eats up all the input up to the end of the input string.
  63. result = parse(test_string, (*anychar_p - '\n') >> '\n');
  64. if (result.full)
  65. {
  66. cout
  67. << "Successfully parsed test string (should not happen)!"
  68. << endl;
  69. }
  70. else
  71. {
  72. cout
  73. << "Correctly failed parsing the test string (without refactoring)!"
  74. << endl;
  75. }
  76. cout << endl;
  77. ///////////////////////////////////////////////////////////////////////////////
  78. //
  79. // 2. Testing the refactor_action_d parser
  80. //
  81. // The following test should successfully parse the test string, because the
  82. //
  83. // refactor_action_d[
  84. // (*(anychar_p - '$'))[refactor_action_actor(str)] >> '$'
  85. // ]
  86. //
  87. // is refactored into
  88. //
  89. // (*(anychar_p - '$') >> '$')[refactor_action_actor(str)].
  90. //
  91. ///////////////////////////////////////////////////////////////////////////////
  92. std::string str;
  93. char const *test_string2 = "Some test string ending with a $";
  94. result =
  95. parse(test_string2,
  96. refactor_action_d[
  97. (*(anychar_p - '$'))[refactor_action_actor(str)] >> '$'
  98. ]
  99. );
  100. if (result.full && str == std::string(test_string2))
  101. {
  102. cout << "Successfully refactored an action!" << endl;
  103. cout << "Parsed: \"" << str << "\"" << endl;
  104. }
  105. else
  106. {
  107. cout << "Failed to refactor an action!" << endl;
  108. }
  109. // Parsing the same test string without refactoring fails, because the
  110. // the attached actor gets called only for the first part of the string
  111. // (without the '$')
  112. result =
  113. parse(test_string2,
  114. (*(anychar_p - '$'))[refactor_action_actor(str)] >> '$'
  115. );
  116. if (result.full && str == std::string(test_string2))
  117. {
  118. cout << "Successfully parsed test string!" << endl;
  119. cout << "Parsed: \"" << str << "\"" << endl;
  120. }
  121. else
  122. {
  123. cout
  124. << "Correctly failed parsing the test string (without refactoring)!"
  125. << endl;
  126. cout << "Parsed instead: \"" << str << "\"" << endl;
  127. }
  128. cout << endl;
  129. ///////////////////////////////////////////////////////////////////////////////
  130. //
  131. // 3. Testing the refactor_action_d parser with an embedded (nested)
  132. // refactor_unary_p parser
  133. //
  134. // The following test should successfully parse the test string, because the
  135. //
  136. // refactor_action_unary_d[
  137. // ((*anychar_p)[refactor_action_actor(str)] - '$')
  138. // ] >> '$'
  139. //
  140. // is refactored into
  141. //
  142. // (*(anychar_p - '$'))[refactor_action_actor(str)] >> '$'.
  143. //
  144. ///////////////////////////////////////////////////////////////////////////////
  145. const refactor_action_gen<refactor_unary_gen<> > refactor_action_unary_d =
  146. refactor_action_gen<refactor_unary_gen<> >(refactor_unary_d);
  147. result =
  148. parse(test_string2,
  149. refactor_action_unary_d[
  150. ((*anychar_p)[refactor_action_actor(str)] - '$')
  151. ] >> '$'
  152. );
  153. if (result.full)
  154. {
  155. cout
  156. << "Successfully refactored an action attached to an unary!"
  157. << endl;
  158. cout << "Parsed: \"" << str << "\"" << endl;
  159. }
  160. else
  161. {
  162. cout << "Failed to refactor an action!" << endl;
  163. }
  164. // Parsing the same test string without refactoring fails, because the
  165. // anychar_p eats up all the input up to the end of the string
  166. result =
  167. parse(test_string2,
  168. ((*anychar_p)[refactor_action_actor(str)] - '$') >> '$'
  169. );
  170. if (result.full)
  171. {
  172. cout << "Successfully parsed test string!" << endl;
  173. cout << "Parsed: \"" << str << "\"" << endl;
  174. }
  175. else
  176. {
  177. cout
  178. << "Correctly failed parsing the test string (without refactoring)!"
  179. << endl;
  180. cout << "Parsed instead: \"" << str << "\"" << endl;
  181. }
  182. cout << endl;
  183. return 0;
  184. }