list_parser.cpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. /*=============================================================================
  2. Copyright (c) 2001-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 sample shows the usage of the list_p utility parser
  10. // 1. parsing a simple ',' delimited list w/o item formatting
  11. // 2. parsing a CSV list (comma separated values - strings, integers or reals)
  12. // 3. parsing a token list (token separated values - strings, integers or
  13. // reals)
  14. // with an action parser directly attached to the item part of the list_p
  15. // generated parser
  16. #include <string>
  17. #include <iostream>
  18. #include <cassert>
  19. #include <vector>
  20. #include <boost/spirit/include/classic_core.hpp>
  21. #include <boost/spirit/include/classic_confix.hpp>
  22. #include <boost/spirit/include/classic_lists.hpp>
  23. #include <boost/spirit/include/classic_escape_char.hpp>
  24. ///////////////////////////////////////////////////////////////////////////////
  25. using namespace std;
  26. using namespace BOOST_SPIRIT_CLASSIC_NS;
  27. ///////////////////////////////////////////////////////////////////////////////
  28. // actor, attached to the list_p parser
  29. class list_actor
  30. {
  31. public:
  32. list_actor (std::vector<std::string> &vec_) : vec(vec_) {}
  33. // The following operator() is called by the action parser generated by
  34. // attaching this actor to a list_p generated list parser.
  35. template <typename ActionIterT>
  36. void operator() (ActionIterT const &first, ActionIterT const &last) const
  37. {
  38. vec.push_back(std::string(first, last-first));
  39. }
  40. private:
  41. std::vector<std::string> &vec;
  42. };
  43. ///////////////////////////////////////////////////////////////////////////////
  44. // main entry point
  45. int main ()
  46. {
  47. // 1. parsing a simple ',' delimited list w/o item formatting
  48. char const* plist_wo_item = "element1,element2,element3";
  49. rule<> list_wo_item;
  50. std::vector<std::string> vec_list;
  51. list_wo_item =
  52. list_p[push_back_a(vec_list)]
  53. ;
  54. parse_info<> result = parse (plist_wo_item, list_wo_item);
  55. cout << "-----------------------------------------------------------------"
  56. << endl;
  57. if (result.hit)
  58. {
  59. cout
  60. << "Parsing simple list" << endl
  61. << "\t" << plist_wo_item << endl
  62. << "Parsed successfully!" << endl << endl;
  63. cout
  64. << "Actor was called " << (int)vec_list.size()
  65. << " times: " << endl;
  66. cout
  67. << "Results got from the list parser:" << endl;
  68. for (std::vector<std::string>::iterator it = vec_list.begin();
  69. it != vec_list.end(); ++it)
  70. {
  71. cout << *it << endl;
  72. }
  73. }
  74. else
  75. {
  76. cout << "Failed to parse simple list!" << endl;
  77. }
  78. cout << endl;
  79. // 2. parsing a CSV list (comma separated values - strings, integers or
  80. // reals)
  81. char const *plist_csv = "\"string\",\"string with an embedded \\\"\","
  82. "12345,0.12345e4,,2";
  83. rule<> list_csv, list_csv_item;
  84. std::vector<std::string> vec_item;
  85. vec_list.clear();
  86. list_csv_item =
  87. !(
  88. confix_p('\"', *c_escape_ch_p, '\"')
  89. | longest_d[real_p | int_p]
  90. );
  91. list_csv =
  92. list_p(
  93. list_csv_item[push_back_a(vec_item)],
  94. ','
  95. )[push_back_a(vec_list)]
  96. ;
  97. result = parse (plist_csv, list_csv);
  98. cout << "-----------------------------------------------------------------"
  99. << endl;
  100. if (result.hit)
  101. {
  102. cout
  103. << "Parsing CSV list (comma separated values) " << endl
  104. << "\t" << plist_csv << endl
  105. << "Parsed successfully!" << endl << endl;
  106. if (result.full)
  107. {
  108. cout << "Matched " << (int)vec_list.size() <<
  109. " list elements (full list): " << endl;
  110. }
  111. else
  112. {
  113. cout << "Matched " << (int)vec_list.size() <<
  114. " list elements: " << endl;
  115. }
  116. cout << "The list parser matched:" << endl;
  117. for (std::vector<std::string>::iterator itl = vec_list.begin();
  118. itl != vec_list.end(); ++itl)
  119. {
  120. cout << *itl << endl;
  121. }
  122. cout << endl << "Item(s) got directly from the item parser:" << endl;
  123. for (std::vector<std::string>::iterator it = vec_item.begin();
  124. it != vec_item.end(); ++it)
  125. {
  126. cout << *it << endl;
  127. }
  128. }
  129. else
  130. {
  131. cout << "Failed to parse CSV list!" << endl;
  132. }
  133. cout << endl;
  134. // 3. parsing a token list (token separated values - strings, integers or
  135. // reals) with an action parser directly attached to the item part of the
  136. // list_p generated parser
  137. char const *plist_csv_direct = "\"string\"<par>\"string with an embedded "
  138. "\\\"\"<par>12345<par>0.12345e4";
  139. rule<> list_csv_direct, list_csv_direct_item;
  140. vec_list.clear();
  141. vec_item.clear();
  142. // Note: the list parser is here generated through the list_p.direct()
  143. // generator function. This inhibits re-attachment of the item_actor_direct
  144. // during parser construction (see: comment in utility/lists.hpp)
  145. list_csv_direct_item =
  146. confix_p('\"', *c_escape_ch_p, '\"')
  147. | longest_d[real_p | int_p]
  148. ;
  149. list_csv_direct =
  150. list_p.direct(
  151. (*list_csv_direct_item)[list_actor(vec_item)],
  152. "<par>"
  153. )[list_actor(vec_list)]
  154. ;
  155. result = parse (plist_csv_direct, list_csv_direct);
  156. cout << "-----------------------------------------------------------------"
  157. << endl;
  158. if (result.hit)
  159. {
  160. cout
  161. << "Parsing CSV list (comma separated values)" << endl
  162. << "The list parser was generated with 'list_p.direct()'" << endl
  163. << "\t" << plist_csv_direct << endl
  164. << "Parsed successfully!" << endl << endl;
  165. if (result.full)
  166. {
  167. cout << "Matched " << vec_list.size() <<
  168. " list elements (full list): " << endl;
  169. }
  170. else
  171. {
  172. cout << "Matched " << vec_list.size() <<
  173. " list elements: " << endl;
  174. }
  175. cout << "The list parser matched:" << endl;
  176. for (std::vector<std::string>::iterator itl = vec_list.begin();
  177. itl != vec_list.end(); ++itl)
  178. {
  179. cout << *itl << endl;
  180. }
  181. cout << endl << "Items got directly from the item parser:" << endl;
  182. for (std::vector<std::string>::iterator it = vec_item.begin();
  183. it != vec_item.end(); ++it)
  184. {
  185. cout << *it << endl;
  186. }
  187. }
  188. else
  189. {
  190. cout << "Failed to parse CSV list!" << endl;
  191. }
  192. cout << endl;
  193. return 0;
  194. }