common.hpp 44 KB

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