/Src/Dependencies/Boost/boost/spirit/home/classic/tree/common.hpp

http://hadesmem.googlecode.com/ · C++ Header · 1588 lines · 1206 code · 240 blank · 142 comment · 63 complexity · 749649c9d44952bc9c561d920e198fa9 MD5 · raw file

  1. /*=============================================================================
  2. Copyright (c) 2001-2003 Daniel Nuffer
  3. Copyright (c) 2001-2007 Hartmut Kaiser
  4. Revised 2007, Copyright (c) Tobias Schwinger
  5. http://spirit.sourceforge.net/
  6. Distributed under the Boost Software License, Version 1.0. (See accompanying
  7. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  8. =============================================================================*/
  9. #ifndef BOOST_SPIRIT_TREE_COMMON_HPP
  10. #define BOOST_SPIRIT_TREE_COMMON_HPP
  11. #if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
  12. #include <vector>
  13. #else
  14. #include <list>
  15. #endif
  16. #if defined(BOOST_SPIRIT_USE_BOOST_ALLOCATOR_FOR_TREES)
  17. #include <boost/pool/pool_alloc.hpp>
  18. #endif
  19. #include <algorithm>
  20. #include <boost/ref.hpp>
  21. #include <boost/call_traits.hpp>
  22. #include <boost/spirit/home/classic/namespace.hpp>
  23. #include <boost/spirit/home/classic/core.hpp>
  24. #include <boost/detail/iterator.hpp> // for boost::detail::iterator_traits
  25. #include <boost/assert.hpp>
  26. #if defined(BOOST_SPIRIT_DEBUG) && \
  27. (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)
  28. #include <iostream>
  29. #include <boost/spirit/home/classic/debug/debug_node.hpp>
  30. #endif
  31. #include <boost/spirit/home/classic/tree/common_fwd.hpp>
  32. namespace boost { namespace spirit {
  33. BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
  34. template <typename T>
  35. void swap(tree_node<T>& a, tree_node<T>& b);
  36. template <typename T, typename V>
  37. void swap(node_iter_data<T, V>& a, node_iter_data<T, V>& b);
  38. namespace impl {
  39. template <typename T>
  40. inline void cp_swap(T& t1, T& t2);
  41. }
  42. template <typename T>
  43. struct tree_node
  44. {
  45. typedef T parse_node_t;
  46. #if !defined(BOOST_SPIRIT_USE_BOOST_ALLOCATOR_FOR_TREES)
  47. typedef std::allocator<tree_node<T> > allocator_type;
  48. #elif !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
  49. typedef boost::pool_allocator<tree_node<T> > allocator_type;
  50. #else
  51. typedef boost::fast_pool_allocator<tree_node<T> > allocator_type;
  52. #endif
  53. #if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
  54. typedef std::vector<tree_node<T>, allocator_type> children_t;
  55. #else
  56. typedef std::list<tree_node<T>, allocator_type> children_t;
  57. #endif // BOOST_SPIRIT_USE_LIST_FOR_TREES
  58. typedef typename children_t::iterator tree_iterator;
  59. typedef typename children_t::const_iterator const_tree_iterator;
  60. T value;
  61. children_t children;
  62. tree_node()
  63. : value()
  64. , children()
  65. {}
  66. explicit tree_node(T const& v)
  67. : value(v)
  68. , children()
  69. {}
  70. tree_node(T const& v, children_t const& c)
  71. : value(v)
  72. , children(c)
  73. {}
  74. void swap(tree_node<T>& x)
  75. {
  76. impl::cp_swap(value, x.value);
  77. impl::cp_swap(children, x.children);
  78. }
  79. // Intel V5.0.1 has a problem without this explicit operator=
  80. tree_node &operator= (tree_node const &rhs)
  81. {
  82. tree_node(rhs).swap(*this);
  83. return *this;
  84. }
  85. };
  86. #if defined(BOOST_SPIRIT_DEBUG) && \
  87. (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)
  88. template <typename T>
  89. inline std::ostream&
  90. operator<<(std::ostream& o, tree_node<T> const& n)
  91. {
  92. static int depth = 0;
  93. o << "\n";
  94. for (int i = 0; i <= depth; ++i)
  95. {
  96. o << "\t";
  97. }
  98. o << "(depth = " << depth++ << " value = " << n.value;
  99. int c = 0;
  100. for (typename tree_node<T>::children_t::const_iterator it = n.children.begin();
  101. it != n.children.end(); ++it)
  102. {
  103. o << " children[" << c++ << "] = " << *it;
  104. }
  105. o << ")";
  106. --depth;
  107. return o;
  108. }
  109. #endif
  110. //////////////////////////////////
  111. template <typename IteratorT, typename ValueT>
  112. struct node_iter_data
  113. {
  114. typedef IteratorT iterator_t;
  115. typedef IteratorT /*const*/ const_iterator_t;
  116. node_iter_data()
  117. : first(), last(), is_root_(false), parser_id_(), value_()
  118. {}
  119. node_iter_data(IteratorT const& _first, IteratorT const& _last)
  120. : first(_first), last(_last), is_root_(false), parser_id_(), value_()
  121. {}
  122. void swap(node_iter_data& x)
  123. {
  124. impl::cp_swap(first, x.first);
  125. impl::cp_swap(last, x.last);
  126. impl::cp_swap(parser_id_, x.parser_id_);
  127. impl::cp_swap(is_root_, x.is_root_);
  128. impl::cp_swap(value_, x.value_);
  129. }
  130. IteratorT begin()
  131. {
  132. return first;
  133. }
  134. IteratorT const& begin() const
  135. {
  136. return first;
  137. }
  138. IteratorT end()
  139. {
  140. return last;
  141. }
  142. IteratorT const& end() const
  143. {
  144. return last;
  145. }
  146. bool is_root() const
  147. {
  148. return is_root_;
  149. }
  150. void is_root(bool b)
  151. {
  152. is_root_ = b;
  153. }
  154. parser_id id() const
  155. {
  156. return parser_id_;
  157. }
  158. void id(parser_id r)
  159. {
  160. parser_id_ = r;
  161. }
  162. ValueT const& value() const
  163. {
  164. return value_;
  165. }
  166. void value(ValueT const& v)
  167. {
  168. value_ = v;
  169. }
  170. private:
  171. IteratorT first, last;
  172. bool is_root_;
  173. parser_id parser_id_;
  174. ValueT value_;
  175. public:
  176. };
  177. #if defined(BOOST_SPIRIT_DEBUG) && \
  178. (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)
  179. // value is default nil_t, so provide an operator<< for nil_t
  180. inline std::ostream&
  181. operator<<(std::ostream& o, nil_t const&)
  182. {
  183. return o;
  184. }
  185. template <typename IteratorT, typename ValueT>
  186. inline std::ostream&
  187. operator<<(std::ostream& o, node_iter_data<IteratorT, ValueT> const& n)
  188. {
  189. o << "(id = " << n.id() << " text = \"";
  190. typedef typename node_iter_data<IteratorT, ValueT>::const_iterator_t
  191. iterator_t;
  192. for (iterator_t it = n.begin(); it != n.end(); ++it)
  193. impl::token_printer(o, *it);
  194. o << "\" is_root = " << n.is_root()
  195. << /*" value = " << n.value() << */")";
  196. return o;
  197. }
  198. #endif
  199. //////////////////////////////////
  200. template <typename IteratorT = char const*, typename ValueT = nil_t>
  201. struct node_val_data
  202. {
  203. typedef
  204. typename boost::detail::iterator_traits<IteratorT>::value_type
  205. value_type;
  206. #if !defined(BOOST_SPIRIT_USE_BOOST_ALLOCATOR_FOR_TREES)
  207. typedef std::allocator<value_type> allocator_type;
  208. #elif !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
  209. typedef boost::pool_allocator<value_type> allocator_type;
  210. #else
  211. typedef boost::fast_pool_allocator<value_type> allocator_type;
  212. #endif
  213. #if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
  214. typedef std::vector<value_type, allocator_type> container_t;
  215. #else
  216. typedef std::list<value_type, allocator_type> container_t;
  217. #endif
  218. typedef typename container_t::iterator iterator_t;
  219. typedef typename container_t::const_iterator const_iterator_t;
  220. node_val_data()
  221. : text(), is_root_(false), parser_id_(), value_()
  222. {}
  223. #if defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)
  224. node_val_data(IteratorT const& _first, IteratorT const& _last)
  225. : text(), is_root_(false), parser_id_(), value_()
  226. {
  227. std::copy(_first, _last, std::inserter(text, text.end()));
  228. }
  229. // This constructor is for building text out of iterators
  230. template <typename IteratorT2>
  231. node_val_data(IteratorT2 const& _first, IteratorT2 const& _last)
  232. : text(), is_root_(false), parser_id_(), value_()
  233. {
  234. std::copy(_first, _last, std::inserter(text, text.end()));
  235. }
  236. #else
  237. node_val_data(IteratorT const& _first, IteratorT const& _last)
  238. : text(_first, _last), is_root_(false), parser_id_(), value_()
  239. {}
  240. // This constructor is for building text out of iterators
  241. template <typename IteratorT2>
  242. node_val_data(IteratorT2 const& _first, IteratorT2 const& _last)
  243. : text(_first, _last), is_root_(false), parser_id_(), value_()
  244. {}
  245. #endif
  246. void swap(node_val_data& x)
  247. {
  248. impl::cp_swap(text, x.text);
  249. impl::cp_swap(is_root_, x.is_root_);
  250. impl::cp_swap(parser_id_, x.parser_id_);
  251. impl::cp_swap(value_, x.value_);
  252. }
  253. typename container_t::iterator begin()
  254. {
  255. return text.begin();
  256. }
  257. typename container_t::const_iterator begin() const
  258. {
  259. return text.begin();
  260. }
  261. typename container_t::iterator end()
  262. {
  263. return text.end();
  264. }
  265. typename container_t::const_iterator end() const
  266. {
  267. return text.end();
  268. }
  269. bool is_root() const
  270. {
  271. return is_root_;
  272. }
  273. void is_root(bool b)
  274. {
  275. is_root_ = b;
  276. }
  277. parser_id id() const
  278. {
  279. return parser_id_;
  280. }
  281. void id(parser_id r)
  282. {
  283. parser_id_ = r;
  284. }
  285. ValueT const& value() const
  286. {
  287. return value_;
  288. }
  289. void value(ValueT const& v)
  290. {
  291. value_ = v;
  292. }
  293. private:
  294. container_t text;
  295. bool is_root_;
  296. parser_id parser_id_;
  297. ValueT value_;
  298. };
  299. #if defined(BOOST_SPIRIT_DEBUG) && \
  300. (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)
  301. template <typename IteratorT, typename ValueT>
  302. inline std::ostream&
  303. operator<<(std::ostream& o, node_val_data<IteratorT, ValueT> const& n)
  304. {
  305. o << "(id = " << n.id() << " text = \"";
  306. typedef typename node_val_data<IteratorT, ValueT>::const_iterator_t
  307. iterator_t;
  308. for (iterator_t it = n.begin(); it != n.end(); ++it)
  309. impl::token_printer(o, *it);
  310. o << "\" is_root = " << n.is_root()
  311. << " value = " << n.value() << ")";
  312. return o;
  313. }
  314. #endif
  315. template <typename T>
  316. inline void
  317. swap(tree_node<T>& a, tree_node<T>& b)
  318. {
  319. a.swap(b);
  320. }
  321. template <typename T, typename V>
  322. inline void
  323. swap(node_iter_data<T, V>& a, node_iter_data<T, V>& b)
  324. {
  325. a.swap(b);
  326. }
  327. //////////////////////////////////
  328. template <typename ValueT>
  329. class node_iter_data_factory
  330. {
  331. public:
  332. // This inner class is so that node_iter_data_factory can simulate
  333. // a template template parameter
  334. template <typename IteratorT>
  335. class factory
  336. {
  337. public:
  338. typedef IteratorT iterator_t;
  339. typedef node_iter_data<iterator_t, ValueT> node_t;
  340. static node_t create_node(iterator_t const& first, iterator_t const& last,
  341. bool /*is_leaf_node*/)
  342. {
  343. return node_t(first, last);
  344. }
  345. static node_t empty_node()
  346. {
  347. return node_t();
  348. }
  349. // precondition: ContainerT contains a tree_node<node_t>. And all
  350. // iterators in the container point to the same sequence.
  351. template <typename ContainerT>
  352. static node_t group_nodes(ContainerT const& nodes)
  353. {
  354. return node_t(nodes.begin()->value.begin(),
  355. nodes.back().value.end());
  356. }
  357. };
  358. };
  359. //////////////////////////////////
  360. template <typename ValueT>
  361. class node_val_data_factory
  362. {
  363. public:
  364. // This inner class is so that node_val_data_factory can simulate
  365. // a template template parameter
  366. template <typename IteratorT>
  367. class factory
  368. {
  369. public:
  370. typedef IteratorT iterator_t;
  371. typedef node_val_data<iterator_t, ValueT> node_t;
  372. static node_t create_node(iterator_t const& first, iterator_t const& last,
  373. bool is_leaf_node)
  374. {
  375. if (is_leaf_node)
  376. return node_t(first, last);
  377. else
  378. return node_t();
  379. }
  380. static node_t empty_node()
  381. {
  382. return node_t();
  383. }
  384. template <typename ContainerT>
  385. static node_t group_nodes(ContainerT const& nodes)
  386. {
  387. typename node_t::container_t c;
  388. typename ContainerT::const_iterator i_end = nodes.end();
  389. // copy all the nodes text into a new one
  390. for (typename ContainerT::const_iterator i = nodes.begin();
  391. i != i_end; ++i)
  392. {
  393. // See docs: reduced_node_d cannot be used with a
  394. // rule inside the [].
  395. BOOST_ASSERT(i->children.size() == 0);
  396. c.insert(c.end(), i->value.begin(), i->value.end());
  397. }
  398. return node_t(c.begin(), c.end());
  399. }
  400. };
  401. };
  402. //////////////////////////////////
  403. template <typename ValueT>
  404. class node_all_val_data_factory
  405. {
  406. public:
  407. // This inner class is so that node_all_val_data_factory can simulate
  408. // a template template parameter
  409. template <typename IteratorT>
  410. class factory
  411. {
  412. public:
  413. typedef IteratorT iterator_t;
  414. typedef node_val_data<iterator_t, ValueT> node_t;
  415. static node_t create_node(iterator_t const& first, iterator_t const& last,
  416. bool /*is_leaf_node*/)
  417. {
  418. return node_t(first, last);
  419. }
  420. static node_t empty_node()
  421. {
  422. return node_t();
  423. }
  424. template <typename ContainerT>
  425. static node_t group_nodes(ContainerT const& nodes)
  426. {
  427. typename node_t::container_t c;
  428. typename ContainerT::const_iterator i_end = nodes.end();
  429. // copy all the nodes text into a new one
  430. for (typename ContainerT::const_iterator i = nodes.begin();
  431. i != i_end; ++i)
  432. {
  433. BOOST_ASSERT(i->children.size() == 0);
  434. c.insert(c.end(), i->value.begin(), i->value.end());
  435. }
  436. return node_t(c.begin(), c.end());
  437. }
  438. };
  439. };
  440. namespace impl {
  441. ///////////////////////////////////////////////////////////////////////////
  442. // can't call unqualified swap from within classname::swap
  443. // as Koenig lookup rules will find only the classname::swap
  444. // member function not the global declaration, so use cp_swap
  445. // as a forwarding function (JM):
  446. #if __GNUC__ == 2
  447. using ::std::swap;
  448. #endif
  449. template <typename T>
  450. inline void cp_swap(T& t1, T& t2)
  451. {
  452. using std::swap;
  453. using BOOST_SPIRIT_CLASSIC_NS::swap;
  454. using boost::swap;
  455. swap(t1, t2);
  456. }
  457. }
  458. //////////////////////////////////
  459. template <typename IteratorT, typename NodeFactoryT, typename T>
  460. class tree_match : public match<T>
  461. {
  462. public:
  463. typedef typename NodeFactoryT::template factory<IteratorT> node_factory_t;
  464. typedef typename node_factory_t::node_t parse_node_t;
  465. typedef tree_node<parse_node_t> node_t;
  466. typedef typename node_t::children_t container_t;
  467. typedef typename container_t::iterator tree_iterator;
  468. typedef typename container_t::const_iterator const_tree_iterator;
  469. typedef T attr_t;
  470. typedef typename boost::call_traits<T>::param_type param_type;
  471. typedef typename boost::call_traits<T>::reference reference;
  472. typedef typename boost::call_traits<T>::const_reference const_reference;
  473. tree_match()
  474. : match<T>(), trees()
  475. {}
  476. explicit
  477. tree_match(std::size_t length_)
  478. : match<T>(length_), trees()
  479. {}
  480. tree_match(std::size_t length_, parse_node_t const& n)
  481. : match<T>(length_), trees()
  482. {
  483. trees.push_back(node_t(n));
  484. }
  485. tree_match(std::size_t length_, param_type val, parse_node_t const& n)
  486. : match<T>(length_, val), trees()
  487. {
  488. #if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
  489. trees.reserve(10); // this is more or less an arbitrary number...
  490. #endif
  491. trees.push_back(node_t(n));
  492. }
  493. // attention, these constructors will change the second parameter!
  494. tree_match(std::size_t length_, container_t& c)
  495. : match<T>(length_), trees()
  496. {
  497. impl::cp_swap(trees, c);
  498. }
  499. tree_match(std::size_t length_, param_type val, container_t& c)
  500. : match<T>(length_, val), trees()
  501. {
  502. impl::cp_swap(trees, c);
  503. }
  504. template <typename T2>
  505. tree_match(match<T2> const& other)
  506. : match<T>(other), trees()
  507. {}
  508. template <typename T2, typename T3, typename T4>
  509. tree_match(tree_match<T2, T3, T4> const& other)
  510. : match<T>(other), trees()
  511. { impl::cp_swap(trees, other.trees); }
  512. template <typename T2>
  513. tree_match&
  514. operator=(match<T2> const& other)
  515. {
  516. match<T>::operator=(other);
  517. return *this;
  518. }
  519. template <typename T2, typename T3, typename T4>
  520. tree_match&
  521. operator=(tree_match<T2, T3, T4> const& other)
  522. {
  523. match<T>::operator=(other);
  524. impl::cp_swap(trees, other.trees);
  525. return *this;
  526. }
  527. tree_match(tree_match const& x)
  528. : match<T>(x), trees()
  529. {
  530. // use auto_ptr like ownership for the trees data member
  531. impl::cp_swap(trees, x.trees);
  532. }
  533. tree_match& operator=(tree_match const& x)
  534. {
  535. tree_match tmp(x);
  536. this->swap(tmp);
  537. return *this;
  538. }
  539. void swap(tree_match& x)
  540. {
  541. match<T>::swap(x);
  542. impl::cp_swap(trees, x.trees);
  543. }
  544. mutable container_t trees;
  545. };
  546. #if defined(BOOST_SPIRIT_DEBUG) && \
  547. (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)
  548. template <typename IteratorT, typename NodeFactoryT, typename T>
  549. inline std::ostream&
  550. operator<<(std::ostream& o, tree_match<IteratorT, NodeFactoryT, T> const& m)
  551. {
  552. typedef
  553. typename tree_match<IteratorT, NodeFactoryT, T>::container_t::iterator
  554. iterator;
  555. o << "(length = " << (int)m.length();
  556. int c = 0;
  557. for (iterator i = m.trees.begin(); i != m.trees.end(); ++i)
  558. {
  559. o << " trees[" << c++ << "] = " << *i;
  560. }
  561. o << "\n)";
  562. return o;
  563. }
  564. #endif
  565. //////////////////////////////////
  566. struct tree_policy
  567. {
  568. template <typename FunctorT, typename MatchT>
  569. static void apply_op_to_match(FunctorT const& /*op*/, MatchT& /*m*/)
  570. {}
  571. template <typename MatchT, typename Iterator1T, typename Iterator2T>
  572. static void group_match(MatchT& /*m*/, parser_id const& /*id*/,
  573. Iterator1T const& /*first*/, Iterator2T const& /*last*/)
  574. {}
  575. template <typename MatchT>
  576. static void concat(MatchT& /*a*/, MatchT const& /*b*/)
  577. {}
  578. };
  579. //////////////////////////////////
  580. template <
  581. typename MatchPolicyT,
  582. typename IteratorT,
  583. typename NodeFactoryT,
  584. typename TreePolicyT,
  585. typename T
  586. >
  587. struct common_tree_match_policy : public match_policy
  588. {
  589. common_tree_match_policy()
  590. {
  591. }
  592. template <typename PolicyT>
  593. common_tree_match_policy(PolicyT const & policies)
  594. : match_policy((match_policy const &)policies)
  595. {
  596. }
  597. template <typename U>
  598. struct result { typedef tree_match<IteratorT, NodeFactoryT, U> type; };
  599. typedef tree_match<IteratorT, NodeFactoryT, T> match_t;
  600. typedef IteratorT iterator_t;
  601. typedef TreePolicyT tree_policy_t;
  602. typedef NodeFactoryT factory_t;
  603. static const match_t no_match() { return match_t(); }
  604. static const match_t empty_match()
  605. { return match_t(0, tree_policy_t::empty_node()); }
  606. template <typename AttrT, typename Iterator1T, typename Iterator2T>
  607. static tree_match<IteratorT, NodeFactoryT, AttrT> create_match(
  608. std::size_t length,
  609. AttrT const& val,
  610. Iterator1T const& first,
  611. Iterator2T const& last)
  612. {
  613. #if defined(BOOST_SPIRIT_DEBUG) && \
  614. (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)
  615. BOOST_SPIRIT_DEBUG_OUT << "\n>>> create_node(begin) <<<\n"
  616. "creating node text: \"";
  617. for (Iterator1T it = first; it != last; ++it)
  618. impl::token_printer(BOOST_SPIRIT_DEBUG_OUT, *it);
  619. BOOST_SPIRIT_DEBUG_OUT << "\"\n";
  620. BOOST_SPIRIT_DEBUG_OUT << ">>> create_node(end) <<<\n\n";
  621. #endif
  622. return tree_match<IteratorT, NodeFactoryT, AttrT>(length, val,
  623. tree_policy_t::create_node(length, first, last, true));
  624. }
  625. template <typename Match1T, typename Match2T>
  626. static void concat_match(Match1T& a, Match2T const& b)
  627. {
  628. #if defined(BOOST_SPIRIT_DEBUG) && \
  629. (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)
  630. BOOST_SPIRIT_DEBUG_OUT << "\n>>> concat_match(begin) <<<\n";
  631. BOOST_SPIRIT_DEBUG_OUT << "tree a:\n" << a << "\n";
  632. BOOST_SPIRIT_DEBUG_OUT << "tree b:\n" << b << "\n";
  633. BOOST_SPIRIT_DEBUG_OUT << ">>> concat_match(end) <<<\n\n";
  634. #endif
  635. BOOST_SPIRIT_ASSERT(a && b);
  636. if (a.length() == 0)
  637. {
  638. a = b;
  639. return;
  640. }
  641. else if (b.length() == 0
  642. #ifdef BOOST_SPIRIT_NO_TREE_NODE_COLLAPSING
  643. && !b.trees.begin()->value.id().to_long()
  644. #endif
  645. )
  646. {
  647. return;
  648. }
  649. a.concat(b);
  650. tree_policy_t::concat(a, b);
  651. }
  652. template <typename MatchT, typename IteratorT2>
  653. void
  654. group_match(
  655. MatchT& m,
  656. parser_id const& id,
  657. IteratorT2 const& first,
  658. IteratorT2 const& last) const
  659. {
  660. if (!m) return;
  661. #if defined(BOOST_SPIRIT_DEBUG) && \
  662. (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_TREES)
  663. BOOST_SPIRIT_DEBUG_OUT << "\n>>> group_match(begin) <<<\n"
  664. "new node(" << id << ") \"";
  665. for (IteratorT2 it = first; it != last; ++it)
  666. impl::token_printer(BOOST_SPIRIT_DEBUG_OUT, *it);
  667. BOOST_SPIRIT_DEBUG_OUT << "\"\n";
  668. BOOST_SPIRIT_DEBUG_OUT << "new child tree (before grouping):\n" << m << "\n";
  669. tree_policy_t::group_match(m, id, first, last);
  670. BOOST_SPIRIT_DEBUG_OUT << "new child tree (after grouping):\n" << m << "\n";
  671. BOOST_SPIRIT_DEBUG_OUT << ">>> group_match(end) <<<\n\n";
  672. #else
  673. tree_policy_t::group_match(m, id, first, last);
  674. #endif
  675. }
  676. };
  677. //////////////////////////////////
  678. template <typename MatchPolicyT, typename NodeFactoryT>
  679. struct common_tree_tree_policy
  680. {
  681. typedef typename MatchPolicyT::iterator_t iterator_t;
  682. typedef typename MatchPolicyT::match_t match_t;
  683. typedef typename NodeFactoryT::template factory<iterator_t> factory_t;
  684. typedef typename factory_t::node_t node_t;
  685. template <typename Iterator1T, typename Iterator2T>
  686. static node_t
  687. create_node(std::size_t /*length*/, Iterator1T const& first,
  688. Iterator2T const& last, bool leaf_node)
  689. {
  690. return factory_t::create_node(first, last, leaf_node);
  691. }
  692. static node_t
  693. empty_node()
  694. {
  695. return factory_t::empty_node();
  696. }
  697. template <typename FunctorT>
  698. static void apply_op_to_match(FunctorT const& op, match_t& m)
  699. {
  700. op(m);
  701. }
  702. };
  703. //////////////////////////////////
  704. // directives to modify how the parse tree is generated
  705. struct no_tree_gen_node_parser_gen;
  706. template <typename T>
  707. struct no_tree_gen_node_parser
  708. : public unary<T, parser<no_tree_gen_node_parser<T> > >
  709. {
  710. typedef no_tree_gen_node_parser<T> self_t;
  711. typedef no_tree_gen_node_parser_gen parser_generator_t;
  712. typedef unary_parser_category parser_category_t;
  713. no_tree_gen_node_parser(T const& a)
  714. : unary<T, parser<no_tree_gen_node_parser<T> > >(a) {}
  715. template <typename ScannerT>
  716. typename parser_result<self_t, ScannerT>::type
  717. parse(ScannerT const& scanner) const
  718. {
  719. typedef typename ScannerT::iteration_policy_t iteration_policy_t;
  720. typedef match_policy match_policy_t;
  721. typedef typename ScannerT::action_policy_t action_policy_t;
  722. typedef scanner_policies<
  723. iteration_policy_t,
  724. match_policy_t,
  725. action_policy_t
  726. > policies_t;
  727. return this->subject().parse(scanner.change_policies(policies_t(scanner)));
  728. }
  729. };
  730. struct no_tree_gen_node_parser_gen
  731. {
  732. template <typename T>
  733. struct result {
  734. typedef no_tree_gen_node_parser<T> type;
  735. };
  736. template <typename T>
  737. static no_tree_gen_node_parser<T>
  738. generate(parser<T> const& s)
  739. {
  740. return no_tree_gen_node_parser<T>(s.derived());
  741. }
  742. template <typename T>
  743. no_tree_gen_node_parser<T>
  744. operator[](parser<T> const& s) const
  745. {
  746. return no_tree_gen_node_parser<T>(s.derived());
  747. }
  748. };
  749. const no_tree_gen_node_parser_gen no_node_d = no_tree_gen_node_parser_gen();
  750. //////////////////////////////////
  751. struct leaf_node_parser_gen;
  752. template<typename T>
  753. struct leaf_node_parser
  754. : public unary<T, parser<leaf_node_parser<T> > >
  755. {
  756. typedef leaf_node_parser<T> self_t;
  757. typedef leaf_node_parser_gen parser_generator_t;
  758. typedef unary_parser_category parser_category_t;
  759. leaf_node_parser(T const& a)
  760. : unary<T, parser<leaf_node_parser<T> > >(a) {}
  761. template <typename ScannerT>
  762. typename parser_result<self_t, ScannerT>::type
  763. parse(ScannerT const& scanner) const
  764. {
  765. typedef scanner_policies< typename ScannerT::iteration_policy_t,
  766. match_policy, typename ScannerT::action_policy_t > policies_t;
  767. typedef typename ScannerT::iterator_t iterator_t;
  768. typedef typename parser_result<self_t, ScannerT>::type result_t;
  769. typedef typename result_t::node_factory_t factory_t;
  770. iterator_t from = scanner.first;
  771. result_t hit = impl::contiguous_parser_parse<result_t>(this->subject(),
  772. scanner.change_policies(policies_t(scanner,match_policy(),scanner)),
  773. scanner);
  774. if (hit)
  775. return result_t(hit.length(),
  776. factory_t::create_node(from, scanner.first, true));
  777. else
  778. return result_t(hit.length());
  779. }
  780. };
  781. struct leaf_node_parser_gen
  782. {
  783. template <typename T>
  784. struct result {
  785. typedef leaf_node_parser<T> type;
  786. };
  787. template <typename T>
  788. static leaf_node_parser<T>
  789. generate(parser<T> const& s)
  790. {
  791. return leaf_node_parser<T>(s.derived());
  792. }
  793. template <typename T>
  794. leaf_node_parser<T>
  795. operator[](parser<T> const& s) const
  796. {
  797. return leaf_node_parser<T>(s.derived());
  798. }
  799. };
  800. const leaf_node_parser_gen leaf_node_d = leaf_node_parser_gen();
  801. const leaf_node_parser_gen token_node_d = leaf_node_parser_gen();
  802. //////////////////////////////////
  803. namespace impl {
  804. template <typename MatchPolicyT>
  805. struct tree_policy_selector
  806. {
  807. typedef tree_policy type;
  808. };
  809. } // namespace impl
  810. //////////////////////////////////
  811. template <typename NodeParserT>
  812. struct node_parser_gen;
  813. template <typename T, typename NodeParserT>
  814. struct node_parser
  815. : public unary<T, parser<node_parser<T, NodeParserT> > >
  816. {
  817. typedef node_parser<T, NodeParserT> self_t;
  818. typedef node_parser_gen<NodeParserT> parser_generator_t;
  819. typedef unary_parser_category parser_category_t;
  820. node_parser(T const& a)
  821. : unary<T, parser<node_parser<T, NodeParserT> > >(a) {}
  822. template <typename ScannerT>
  823. struct result
  824. {
  825. typedef typename parser_result<T, ScannerT>::type type;
  826. };
  827. template <typename ScannerT>
  828. typename parser_result<self_t, ScannerT>::type
  829. parse(ScannerT const& scanner) const
  830. {
  831. typename parser_result<self_t, ScannerT>::type hit = this->subject().parse(scanner);
  832. if (hit)
  833. {
  834. impl::tree_policy_selector<typename ScannerT::match_policy_t>::type::apply_op_to_match(NodeParserT(), hit);
  835. }
  836. return hit;
  837. }
  838. };
  839. template <typename NodeParserT>
  840. struct node_parser_gen
  841. {
  842. template <typename T>
  843. struct result {
  844. typedef node_parser<T, NodeParserT> type;
  845. };
  846. template <typename T>
  847. static node_parser<T, NodeParserT>
  848. generate(parser<T> const& s)
  849. {
  850. return node_parser<T, NodeParserT>(s.derived());
  851. }
  852. template <typename T>
  853. node_parser<T, NodeParserT>
  854. operator[](parser<T> const& s) const
  855. {
  856. return node_parser<T, NodeParserT>(s.derived());
  857. }
  858. };
  859. //////////////////////////////////
  860. struct reduced_node_op
  861. {
  862. template <typename MatchT>
  863. void operator()(MatchT& m) const
  864. {
  865. if (m.trees.size() == 1)
  866. {
  867. m.trees.begin()->children.clear();
  868. }
  869. else if (m.trees.size() > 1)
  870. {
  871. typedef typename MatchT::node_factory_t node_factory_t;
  872. m = MatchT(m.length(), node_factory_t::group_nodes(m.trees));
  873. }
  874. }
  875. };
  876. const node_parser_gen<reduced_node_op> reduced_node_d =
  877. node_parser_gen<reduced_node_op>();
  878. struct discard_node_op
  879. {
  880. template <typename MatchT>
  881. void operator()(MatchT& m) const
  882. {
  883. m.trees.clear();
  884. }
  885. };
  886. const node_parser_gen<discard_node_op> discard_node_d =
  887. node_parser_gen<discard_node_op>();
  888. struct infix_node_op
  889. {
  890. template <typename MatchT>
  891. void operator()(MatchT& m) const
  892. {
  893. typedef typename MatchT::container_t container_t;
  894. typedef typename MatchT::container_t::iterator iter_t;
  895. typedef typename MatchT::container_t::value_type value_t;
  896. using std::swap;
  897. using boost::swap;
  898. using BOOST_SPIRIT_CLASSIC_NS::swap;
  899. // copying the tree nodes is expensive, since it may copy a whole
  900. // tree. swapping them is cheap, so swap the nodes we want into
  901. // a new container of children.
  902. container_t new_children;
  903. std::size_t length = 0;
  904. std::size_t tree_size = m.trees.size();
  905. // the infix_node_d[] make no sense for nodes with no subnodes
  906. BOOST_SPIRIT_ASSERT(tree_size >= 1);
  907. bool keep = true;
  908. #if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
  909. new_children.reserve((tree_size+1)/2);
  910. #endif
  911. iter_t i_end = m.trees.end();
  912. for (iter_t i = m.trees.begin(); i != i_end; ++i)
  913. {
  914. if (keep) {
  915. // adjust the length
  916. length += std::distance((*i).value.begin(), (*i).value.end());
  917. // move the child node
  918. new_children.push_back(value_t());
  919. swap(new_children.back(), *i);
  920. keep = false;
  921. }
  922. else {
  923. // ignore this child node
  924. keep = true;
  925. }
  926. }
  927. m = MatchT(length, new_children);
  928. }
  929. };
  930. const node_parser_gen<infix_node_op> infix_node_d =
  931. node_parser_gen<infix_node_op>();
  932. struct discard_first_node_op
  933. {
  934. template <typename MatchT>
  935. void operator()(MatchT& m) const
  936. {
  937. typedef typename MatchT::container_t container_t;
  938. typedef typename MatchT::container_t::iterator iter_t;
  939. typedef typename MatchT::container_t::value_type value_t;
  940. using std::swap;
  941. using boost::swap;
  942. using BOOST_SPIRIT_CLASSIC_NS::swap;
  943. // copying the tree nodes is expensive, since it may copy a whole
  944. // tree. swapping them is cheap, so swap the nodes we want into
  945. // a new container of children, instead of saying
  946. // m.trees.erase(m.trees.begin()) because, on a container_t that will
  947. // cause all the nodes afterwards to be copied into the previous
  948. // position.
  949. container_t new_children;
  950. std::size_t length = 0;
  951. std::size_t tree_size = m.trees.size();
  952. // the discard_first_node_d[] make no sense for nodes with no subnodes
  953. BOOST_SPIRIT_ASSERT(tree_size >= 1);
  954. if (tree_size > 1) {
  955. #if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
  956. new_children.reserve(tree_size - 1);
  957. #endif
  958. iter_t i = m.trees.begin(), i_end = m.trees.end();
  959. for (++i; i != i_end; ++i)
  960. {
  961. // adjust the length
  962. length += std::distance((*i).value.begin(), (*i).value.end());
  963. // move the child node
  964. new_children.push_back(value_t());
  965. swap(new_children.back(), *i);
  966. }
  967. }
  968. else {
  969. // if there was a tree and now there isn't any, insert an empty node
  970. iter_t i = m.trees.begin();
  971. // This isn't entirely correct, since the empty node will reference
  972. // the end of the discarded node, but I currently don't see any way to
  973. // get at the begin of the node following this subnode.
  974. // This should be safe anyway because the it shouldn't get dereferenced
  975. // under any circumstances.
  976. typedef typename value_t::parse_node_t::iterator_t iterator_type;
  977. iterator_type it = (*i).value.end();
  978. new_children.push_back(
  979. value_t(typename value_t::parse_node_t(it, it)));
  980. }
  981. m = MatchT(length, new_children);
  982. }
  983. };
  984. const node_parser_gen<discard_first_node_op> discard_first_node_d =
  985. node_parser_gen<discard_first_node_op>();
  986. struct discard_last_node_op
  987. {
  988. template <typename MatchT>
  989. void operator()(MatchT& m) const
  990. {
  991. typedef typename MatchT::container_t container_t;
  992. typedef typename MatchT::container_t::iterator iter_t;
  993. typedef typename MatchT::container_t::value_type value_t;
  994. using std::swap;
  995. using boost::swap;
  996. using BOOST_SPIRIT_CLASSIC_NS::swap;
  997. // copying the tree nodes is expensive, since it may copy a whole
  998. // tree. swapping them is cheap, so swap the nodes we want into
  999. // a new container of children, instead of saying
  1000. // m.trees.erase(m.trees.begin()) because, on a container_t that will
  1001. // cause all the nodes afterwards to be copied into the previous
  1002. // position.
  1003. container_t new_children;
  1004. std::size_t length = 0;
  1005. std::size_t tree_size = m.trees.size();
  1006. // the discard_last_node_d[] make no sense for nodes with no subnodes
  1007. BOOST_SPIRIT_ASSERT(tree_size >= 1);
  1008. if (tree_size > 1) {
  1009. m.trees.pop_back();
  1010. #if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
  1011. new_children.reserve(tree_size - 1);
  1012. #endif
  1013. iter_t i_end = m.trees.end();
  1014. for (iter_t i = m.trees.begin(); i != i_end; ++i)
  1015. {
  1016. // adjust the length
  1017. length += std::distance((*i).value.begin(), (*i).value.end());
  1018. // move the child node
  1019. new_children.push_back(value_t());
  1020. swap(new_children.back(), *i);
  1021. }
  1022. }
  1023. else {
  1024. // if there was a tree and now there isn't any, insert an empty node
  1025. iter_t i = m.trees.begin();
  1026. typedef typename value_t::parse_node_t::iterator_t iterator_type;
  1027. iterator_type it = (*i).value.begin();
  1028. new_children.push_back(
  1029. value_t(typename value_t::parse_node_t(it, it)));
  1030. }
  1031. m = MatchT(length, new_children);
  1032. }
  1033. };
  1034. const node_parser_gen<discard_last_node_op> discard_last_node_d =
  1035. node_parser_gen<discard_last_node_op>();
  1036. struct inner_node_op
  1037. {
  1038. template <typename MatchT>
  1039. void operator()(MatchT& m) const
  1040. {
  1041. typedef typename MatchT::container_t container_t;
  1042. typedef typename MatchT::container_t::iterator iter_t;
  1043. typedef typename MatchT::container_t::value_type value_t;
  1044. using std::swap;
  1045. using boost::swap;
  1046. using BOOST_SPIRIT_CLASSIC_NS::swap;
  1047. // copying the tree nodes is expensive, since it may copy a whole
  1048. // tree. swapping them is cheap, so swap the nodes we want into
  1049. // a new container of children, instead of saying
  1050. // m.trees.erase(m.trees.begin()) because, on a container_t that will
  1051. // cause all the nodes afterwards to be copied into the previous
  1052. // position.
  1053. container_t new_children;
  1054. std::size_t length = 0;
  1055. std::size_t tree_size = m.trees.size();
  1056. // the inner_node_d[] make no sense for nodes with less then 2 subnodes
  1057. BOOST_SPIRIT_ASSERT(tree_size >= 2);
  1058. if (tree_size > 2) {
  1059. m.trees.pop_back(); // erase the last element
  1060. #if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
  1061. new_children.reserve(tree_size - 1);
  1062. #endif
  1063. iter_t i = m.trees.begin(); // skip over the first element
  1064. iter_t i_end = m.trees.end();
  1065. for (++i; i != i_end; ++i)
  1066. {
  1067. // adjust the length
  1068. length += std::distance((*i).value.begin(), (*i).value.end());
  1069. // move the child node
  1070. new_children.push_back(value_t());
  1071. swap(new_children.back(), *i);
  1072. }
  1073. }
  1074. else {
  1075. // if there was a tree and now there isn't any, insert an empty node
  1076. iter_t i = m.trees.begin(); // skip over the first element
  1077. typedef typename value_t::parse_node_t::iterator_t iterator_type;
  1078. iterator_type it = (*++i).value.begin();
  1079. new_children.push_back(
  1080. value_t(typename value_t::parse_node_t(it, it)));
  1081. }
  1082. m = MatchT(length, new_children);
  1083. }
  1084. };
  1085. const node_parser_gen<inner_node_op> inner_node_d =
  1086. node_parser_gen<inner_node_op>();
  1087. //////////////////////////////////
  1088. // action_directive_parser and action_directive_parser_gen
  1089. // are meant to be used as a template to create directives that
  1090. // generate action classes. For example access_match and
  1091. // access_node. The ActionParserT template parameter must be
  1092. // a class that has an innter class called action that is templated
  1093. // on the parser type and the action type.
  1094. template <typename ActionParserT>
  1095. struct action_directive_parser_gen;
  1096. template <typename T, typename ActionParserT>
  1097. struct action_directive_parser
  1098. : public unary<T, parser<action_directive_parser<T, ActionParserT> > >
  1099. {
  1100. typedef action_directive_parser<T, ActionParserT> self_t;
  1101. typedef action_directive_parser_gen<ActionParserT> parser_generator_t;
  1102. typedef unary_parser_category parser_category_t;
  1103. action_directive_parser(T const& a)
  1104. : unary<T, parser<action_directive_parser<T, ActionParserT> > >(a) {}
  1105. template <typename ScannerT>
  1106. struct result
  1107. {
  1108. typedef typename parser_result<T, ScannerT>::type type;
  1109. };
  1110. template <typename ScannerT>
  1111. typename parser_result<self_t, ScannerT>::type
  1112. parse(ScannerT const& scanner) const
  1113. {
  1114. return this->subject().parse(scanner);
  1115. }
  1116. template <typename ActionT>
  1117. typename ActionParserT::template action<action_directive_parser<T, ActionParserT>, ActionT>
  1118. operator[](ActionT const& actor) const
  1119. {
  1120. typedef typename
  1121. ActionParserT::template action<action_directive_parser, ActionT>
  1122. action_t;
  1123. return action_t(*this, actor);
  1124. }
  1125. };
  1126. //////////////////////////////////
  1127. template <typename ActionParserT>
  1128. struct action_directive_parser_gen
  1129. {
  1130. template <typename T>
  1131. struct result {
  1132. typedef action_directive_parser<T, ActionParserT> type;
  1133. };
  1134. template <typename T>
  1135. static action_directive_parser<T, ActionParserT>
  1136. generate(parser<T> const& s)
  1137. {
  1138. return action_directive_parser<T, ActionParserT>(s.derived());
  1139. }
  1140. template <typename T>
  1141. action_directive_parser<T, ActionParserT>
  1142. operator[](parser<T> const& s) const
  1143. {
  1144. return action_directive_parser<T, ActionParserT>(s.derived());
  1145. }
  1146. };
  1147. //////////////////////////////////
  1148. // Calls the attached action passing it the match from the parser
  1149. // and the first and last iterators.
  1150. // The inner template class is used to simulate template-template parameters
  1151. // (declared in common_fwd.hpp).
  1152. template <typename ParserT, typename ActionT>
  1153. struct access_match_action::action
  1154. : public unary<ParserT, parser<access_match_action::action<ParserT, ActionT> > >
  1155. {
  1156. typedef action_parser_category parser_category;
  1157. typedef action<ParserT, ActionT> self_t;
  1158. template <typename ScannerT>
  1159. struct result
  1160. {
  1161. typedef typename parser_result<ParserT, ScannerT>::type type;
  1162. };
  1163. action( ParserT const& subject,
  1164. ActionT const& actor_);
  1165. template <typename ScannerT>
  1166. typename parser_result<self_t, ScannerT>::type
  1167. parse(ScannerT const& scanner) const;
  1168. ActionT const &predicate() const;
  1169. private:
  1170. ActionT actor;
  1171. };
  1172. //////////////////////////////////
  1173. template <typename ParserT, typename ActionT>
  1174. access_match_action::action<ParserT, ActionT>::action(
  1175. ParserT const& subject,
  1176. ActionT const& actor_)
  1177. : unary<ParserT, parser<access_match_action::action<ParserT, ActionT> > >(subject)
  1178. , actor(actor_)
  1179. {}
  1180. //////////////////////////////////
  1181. template <typename ParserT, typename ActionT>
  1182. template <typename ScannerT>
  1183. typename parser_result<access_match_action::action<ParserT, ActionT>, ScannerT>::type
  1184. access_match_action::action<ParserT, ActionT>::
  1185. parse(ScannerT const& scan) const
  1186. {
  1187. typedef typename ScannerT::iterator_t iterator_t;
  1188. typedef typename parser_result<self_t, ScannerT>::type result_t;
  1189. if (!scan.at_end())
  1190. {
  1191. iterator_t save = scan.first;
  1192. result_t hit = this->subject().parse(scan);
  1193. actor(hit, save, scan.first);
  1194. return hit;
  1195. }
  1196. return scan.no_match();
  1197. }
  1198. //////////////////////////////////
  1199. template <typename ParserT, typename ActionT>
  1200. ActionT const &access_match_action::action<ParserT, ActionT>::predicate() const
  1201. {
  1202. return actor;
  1203. }
  1204. //////////////////////////////////
  1205. const action_directive_parser_gen<access_match_action> access_match_d
  1206. = action_directive_parser_gen<access_match_action>();
  1207. //////////////////////////////////
  1208. // Calls the attached action passing it the node from the parser
  1209. // and the first and last iterators
  1210. // The inner template class is used to simulate template-template parameters
  1211. // (declared in common_fwd.hpp).
  1212. template <typename ParserT, typename ActionT>
  1213. struct access_node_action::action
  1214. : public unary<ParserT, parser<access_node_action::action<ParserT, ActionT> > >
  1215. {
  1216. typedef action_parser_category parser_category;
  1217. typedef action<ParserT, ActionT> self_t;
  1218. template <typename ScannerT>
  1219. struct result
  1220. {
  1221. typedef typename parser_result<ParserT, ScannerT>::type type;
  1222. };
  1223. action( ParserT const& subject,
  1224. ActionT const& actor_);
  1225. template <typename ScannerT>
  1226. typename parser_result<self_t, ScannerT>::type
  1227. parse(ScannerT const& scanner) const;
  1228. ActionT const &predicate() const;
  1229. private:
  1230. ActionT actor;
  1231. };
  1232. //////////////////////////////////
  1233. template <typename ParserT, typename ActionT>
  1234. access_node_action::action<ParserT, ActionT>::action(
  1235. ParserT const& subject,
  1236. ActionT const& actor_)
  1237. : unary<ParserT, parser<access_node_action::action<ParserT, ActionT> > >(subject)
  1238. , actor(actor_)
  1239. {}
  1240. //////////////////////////////////
  1241. template <typename ParserT, typename ActionT>
  1242. template <typename ScannerT>
  1243. typename parser_result<access_node_action::action<ParserT, ActionT>, ScannerT>::type
  1244. access_node_action::action<ParserT, ActionT>::
  1245. parse(ScannerT const& scan) const
  1246. {
  1247. typedef typename ScannerT::iterator_t iterator_t;
  1248. typedef typename parser_result<self_t, ScannerT>::type result_t;
  1249. if (!scan.at_end())
  1250. {
  1251. iterator_t save = scan.first;
  1252. result_t hit = this->subject().parse(scan);
  1253. if (hit && hit.trees.size() > 0)
  1254. actor(*hit.trees.begin(), save, scan.first);
  1255. return hit;
  1256. }
  1257. return scan.no_match();
  1258. }
  1259. //////////////////////////////////
  1260. template <typename ParserT, typename ActionT>
  1261. ActionT const &access_node_action::action<ParserT, ActionT>::predicate() const
  1262. {
  1263. return actor;
  1264. }
  1265. //////////////////////////////////
  1266. const action_directive_parser_gen<access_node_action> access_node_d
  1267. = action_directive_parser_gen<access_node_action>();
  1268. //////////////////////////////////
  1269. ///////////////////////////////////////////////////////////////////////////////
  1270. //
  1271. // tree_parse_info
  1272. //
  1273. // Results returned by the tree parse functions:
  1274. //
  1275. // stop: points to the final parse position (i.e parsing
  1276. // processed the input up to this point).
  1277. //
  1278. // match: true if parsing is successful. This may be full:
  1279. // the parser consumed all the input, or partial:
  1280. // the parser consumed only a portion of the input.
  1281. //
  1282. // full: true when we have a full match (i.e the parser
  1283. // consumed all the input.
  1284. //
  1285. // length: The number of characters consumed by the parser.
  1286. // This is valid only if we have a successful match
  1287. // (either partial or full). A negative value means
  1288. // that the match is unsucessful.
  1289. //
  1290. // trees: Contains the root node(s) of the tree.
  1291. //
  1292. ///////////////////////////////////////////////////////////////////////////////
  1293. template <
  1294. typename IteratorT,
  1295. typename NodeFactoryT,
  1296. typename T
  1297. >
  1298. struct tree_parse_info
  1299. {
  1300. IteratorT stop;
  1301. bool match;
  1302. bool full;
  1303. std::size_t length;
  1304. typename tree_match<IteratorT, NodeFactoryT, T>::container_t trees;
  1305. tree_parse_info()
  1306. : stop()
  1307. , match(false)
  1308. , full(false)
  1309. , length(0)
  1310. , trees()
  1311. {}
  1312. template <typename IteratorT2>
  1313. tree_parse_info(tree_parse_info<IteratorT2> const& pi)
  1314. : stop(pi.stop)
  1315. , match(pi.match)
  1316. , full(pi.full)
  1317. , length(pi.length)
  1318. , trees()
  1319. {
  1320. using std::swap;
  1321. using boost::swap;
  1322. using BOOST_SPIRIT_CLASSIC_NS::swap;
  1323. // use auto_ptr like ownership for the trees data member
  1324. swap(trees, pi.trees);
  1325. }
  1326. tree_parse_info(
  1327. IteratorT stop_,
  1328. bool match_,
  1329. bool full_,
  1330. std::size_t length_,
  1331. typename tree_match<IteratorT, NodeFactoryT, T>::container_t trees_)
  1332. : stop(stop_)
  1333. , match(match_)
  1334. , full(full_)
  1335. , length(length_)
  1336. , trees()
  1337. {
  1338. using std::swap;
  1339. using boost::swap;
  1340. using BOOST_SPIRIT_CLASSIC_NS::swap;
  1341. // use auto_ptr like ownership for the trees data member
  1342. swap(trees, trees_);
  1343. }
  1344. };
  1345. BOOST_SPIRIT_CLASSIC_NAMESPACE_END
  1346. }} // namespace BOOST_SPIRIT_CLASSIC_NS
  1347. #endif