parse_tree.hpp 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. /*=============================================================================
  2. Copyright (c) 2001-2003 Daniel Nuffer
  3. Copyright (c) 2001-2007 Hartmut Kaiser
  4. http://spirit.sourceforge.net/
  5. Distributed under the Boost Software License, Version 1.0. (See accompanying
  6. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. =============================================================================*/
  8. #ifndef BOOST_SPIRIT_TREE_PARSE_TREE_HPP
  9. #define BOOST_SPIRIT_TREE_PARSE_TREE_HPP
  10. #include <boost/spirit/home/classic/namespace.hpp>
  11. #include <boost/spirit/home/classic/tree/common.hpp>
  12. #include <boost/spirit/home/classic/core/scanner/scanner.hpp>
  13. #include <boost/spirit/home/classic/tree/parse_tree_fwd.hpp>
  14. ///////////////////////////////////////////////////////////////////////////////
  15. namespace boost { namespace spirit {
  16. BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
  17. //////////////////////////////////
  18. // pt_match_policy is simply an id so the correct specialization of tree_policy can be found.
  19. template <
  20. typename IteratorT,
  21. typename NodeFactoryT,
  22. typename T
  23. >
  24. struct pt_match_policy :
  25. public common_tree_match_policy<
  26. pt_match_policy<IteratorT, NodeFactoryT, T>,
  27. IteratorT,
  28. NodeFactoryT,
  29. pt_tree_policy<
  30. pt_match_policy<IteratorT, NodeFactoryT, T>,
  31. NodeFactoryT,
  32. T
  33. >,
  34. T
  35. >
  36. {
  37. typedef
  38. common_tree_match_policy<
  39. pt_match_policy<IteratorT, NodeFactoryT, T>,
  40. IteratorT,
  41. NodeFactoryT,
  42. pt_tree_policy<
  43. pt_match_policy<IteratorT, NodeFactoryT, T>,
  44. NodeFactoryT,
  45. T
  46. >,
  47. T
  48. >
  49. common_tree_match_policy_;
  50. pt_match_policy()
  51. {
  52. }
  53. template <typename PolicyT>
  54. pt_match_policy(PolicyT const & policies)
  55. : common_tree_match_policy_(policies)
  56. {
  57. }
  58. };
  59. //////////////////////////////////
  60. template <typename MatchPolicyT, typename NodeFactoryT, typename T>
  61. struct pt_tree_policy :
  62. public common_tree_tree_policy<MatchPolicyT, NodeFactoryT>
  63. {
  64. typedef typename MatchPolicyT::match_t match_t;
  65. typedef typename MatchPolicyT::iterator_t iterator_t;
  66. template<typename MatchAT, typename MatchBT>
  67. static void concat(MatchAT& a, MatchBT const& b)
  68. {
  69. typedef typename match_t::attr_t attr_t;
  70. BOOST_SPIRIT_ASSERT(a && b);
  71. std::copy(b.trees.begin(), b.trees.end(),
  72. std::back_insert_iterator<typename match_t::container_t>(a.trees));
  73. }
  74. template <typename MatchT, typename Iterator1T, typename Iterator2T>
  75. static void group_match(MatchT& m, parser_id const& id,
  76. Iterator1T const& first, Iterator2T const& last)
  77. {
  78. if (!m)
  79. return;
  80. typedef typename NodeFactoryT::template factory<iterator_t> factory_t;
  81. typedef typename tree_match<iterator_t, NodeFactoryT, T>::container_t
  82. container_t;
  83. typedef typename container_t::iterator cont_iterator_t;
  84. match_t newmatch(m.length(),
  85. factory_t::create_node(first, last, false));
  86. std::swap(newmatch.trees.begin()->children, m.trees);
  87. // set this node and all it's unset children's rule_id
  88. newmatch.trees.begin()->value.id(id);
  89. for (cont_iterator_t i = newmatch.trees.begin()->children.begin();
  90. i != newmatch.trees.begin()->children.end();
  91. ++i)
  92. {
  93. if (i->value.id() == 0)
  94. i->value.id(id);
  95. }
  96. m = newmatch;
  97. }
  98. template <typename FunctorT, typename MatchT>
  99. static void apply_op_to_match(FunctorT const& op, MatchT& m)
  100. {
  101. op(m);
  102. }
  103. };
  104. namespace impl {
  105. template <typename IteratorT, typename NodeFactoryT, typename T>
  106. struct tree_policy_selector<pt_match_policy<IteratorT, NodeFactoryT, T> >
  107. {
  108. typedef pt_tree_policy<
  109. pt_match_policy<IteratorT, NodeFactoryT, T>,
  110. NodeFactoryT,
  111. T
  112. > type;
  113. };
  114. } // namespace impl
  115. //////////////////////////////////
  116. struct gen_pt_node_parser_gen;
  117. template <typename T>
  118. struct gen_pt_node_parser
  119. : public unary<T, parser<gen_pt_node_parser<T> > >
  120. {
  121. typedef gen_pt_node_parser<T> self_t;
  122. typedef gen_pt_node_parser_gen parser_generator_t;
  123. typedef unary_parser_category parser_category_t;
  124. gen_pt_node_parser(T const& a)
  125. : unary<T, parser<gen_pt_node_parser<T> > >(a) {}
  126. template <typename ScannerT>
  127. typename parser_result<self_t, ScannerT>::type
  128. parse(ScannerT const& scan) const
  129. {
  130. typedef typename ScannerT::iteration_policy_t iteration_policy_t;
  131. typedef typename ScannerT::match_policy_t::iterator_t iterator_t;
  132. typedef typename ScannerT::match_policy_t::factory_t factory_t;
  133. typedef pt_match_policy<iterator_t, factory_t> match_policy_t;
  134. typedef typename ScannerT::action_policy_t action_policy_t;
  135. typedef scanner_policies<
  136. iteration_policy_t,
  137. match_policy_t,
  138. action_policy_t
  139. > policies_t;
  140. return this->subject().parse(scan.change_policies(policies_t(scan)));
  141. }
  142. };
  143. //////////////////////////////////
  144. struct gen_pt_node_parser_gen
  145. {
  146. template <typename T>
  147. struct result {
  148. typedef gen_pt_node_parser<T> type;
  149. };
  150. template <typename T>
  151. static gen_pt_node_parser<T>
  152. generate(parser<T> const& s)
  153. {
  154. return gen_pt_node_parser<T>(s.derived());
  155. }
  156. template <typename T>
  157. gen_pt_node_parser<T>
  158. operator[](parser<T> const& s) const
  159. {
  160. return gen_pt_node_parser<T>(s.derived());
  161. }
  162. };
  163. //////////////////////////////////
  164. const gen_pt_node_parser_gen gen_pt_node_d = gen_pt_node_parser_gen();
  165. ///////////////////////////////////////////////////////////////////////////////
  166. //
  167. // Parse functions for parse trees
  168. //
  169. ///////////////////////////////////////////////////////////////////////////////
  170. template <
  171. typename NodeFactoryT, typename IteratorT, typename ParserT,
  172. typename SkipT
  173. >
  174. inline tree_parse_info<IteratorT, NodeFactoryT>
  175. pt_parse(
  176. IteratorT const& first_,
  177. IteratorT const& last,
  178. parser<ParserT> const& p,
  179. SkipT const& skip,
  180. NodeFactoryT const& /*dummy_*/ = NodeFactoryT())
  181. {
  182. typedef skip_parser_iteration_policy<SkipT> iter_policy_t;
  183. typedef pt_match_policy<IteratorT, NodeFactoryT> pt_match_policy_t;
  184. typedef
  185. scanner_policies<iter_policy_t, pt_match_policy_t>
  186. scanner_policies_t;
  187. typedef scanner<IteratorT, scanner_policies_t> scanner_t;
  188. iter_policy_t iter_policy(skip);
  189. scanner_policies_t policies(iter_policy);
  190. IteratorT first = first_;
  191. scanner_t scan(first, last, policies);
  192. tree_match<IteratorT, NodeFactoryT> hit = p.derived().parse(scan);
  193. return tree_parse_info<IteratorT, NodeFactoryT>(
  194. first, hit, hit && (first == last), hit.length(), hit.trees);
  195. }
  196. template <typename IteratorT, typename ParserT, typename SkipT>
  197. inline tree_parse_info<IteratorT>
  198. pt_parse(
  199. IteratorT const& first,
  200. IteratorT const& last,
  201. parser<ParserT> const& p,
  202. SkipT const& skip)
  203. {
  204. typedef node_val_data_factory<nil_t> default_node_factory_t;
  205. return pt_parse(first, last, p, skip, default_node_factory_t());
  206. }
  207. //////////////////////////////////
  208. template <typename IteratorT, typename ParserT>
  209. inline tree_parse_info<IteratorT>
  210. pt_parse(
  211. IteratorT const& first_,
  212. IteratorT const& last,
  213. parser<ParserT> const& parser)
  214. {
  215. typedef pt_match_policy<IteratorT> pt_match_policy_t;
  216. IteratorT first = first_;
  217. scanner<
  218. IteratorT,
  219. scanner_policies<iteration_policy, pt_match_policy_t>
  220. > scan(first, last);
  221. tree_match<IteratorT> hit = parser.derived().parse(scan);
  222. return tree_parse_info<IteratorT>(
  223. first, hit, hit && (first == last), hit.length(), hit.trees);
  224. }
  225. //////////////////////////////////
  226. template <typename CharT, typename ParserT, typename SkipT>
  227. inline tree_parse_info<CharT const*>
  228. pt_parse(
  229. CharT const* str,
  230. parser<ParserT> const& p,
  231. SkipT const& skip)
  232. {
  233. CharT const* last = str;
  234. while (*last)
  235. last++;
  236. return pt_parse(str, last, p, skip);
  237. }
  238. //////////////////////////////////
  239. template <typename CharT, typename ParserT>
  240. inline tree_parse_info<CharT const*>
  241. pt_parse(
  242. CharT const* str,
  243. parser<ParserT> const& parser)
  244. {
  245. CharT const* last = str;
  246. while (*last)
  247. {
  248. last++;
  249. }
  250. return pt_parse(str, last, parser);
  251. }
  252. ///////////////////////////////////////////////////////////////////////////////
  253. BOOST_SPIRIT_CLASSIC_NAMESPACE_END
  254. }} // namespace BOOST_SPIRIT_CLASSIC_NS
  255. #endif