/src/contrib/boost/spirit/home/classic/tree/common.hpp

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