parse_tree_utils.ipp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /*=============================================================================
  2. Copyright (c) 2001-2007 Hartmut Kaiser
  3. Copyright (c) 2001-2003 Daniel Nuffer
  4. http://spirit.sourceforge.net/
  5. Use, modification and distribution is subject to the Boost Software
  6. License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  7. http://www.boost.org/LICENSE_1_0.txt)
  8. =============================================================================*/
  9. #ifndef BOOST_SPIRIT_CLASSIC_TREE_IMPL_PARSE_TREE_UTILS_IPP
  10. #define BOOST_SPIRIT_CLASSIC_TREE_IMPL_PARSE_TREE_UTILS_IPP
  11. ///////////////////////////////////////////////////////////////////////////////
  12. namespace boost {
  13. namespace spirit {
  14. BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
  15. ///////////////////////////////////////////////////////////////////////////////
  16. //
  17. // Returnes the first leaf node of the given parsetree.
  18. //
  19. ///////////////////////////////////////////////////////////////////////////////
  20. template <typename T>
  21. inline tree_node<T> const &
  22. get_first_leaf (tree_node<T> const &node)
  23. {
  24. if (node.children.size() > 0)
  25. return get_first_leaf(*node.children.begin());
  26. return node;
  27. }
  28. ///////////////////////////////////////////////////////////////////////////////
  29. //
  30. // Find a specified node through recursive search.
  31. //
  32. ///////////////////////////////////////////////////////////////////////////////
  33. template <typename T>
  34. inline bool
  35. find_node (tree_node<T> const &node, parser_id node_to_search,
  36. tree_node<T> const **found_node)
  37. {
  38. if (node.value.id() == node_to_search) {
  39. *found_node = &node;
  40. return true;
  41. }
  42. if (node.children.size() > 0) {
  43. typedef typename tree_node<T>::const_tree_iterator const_tree_iterator;
  44. const_tree_iterator end = node.children.end();
  45. for (const_tree_iterator it = node.children.begin(); it != end; ++it)
  46. {
  47. if (find_node (*it, node_to_search, found_node))
  48. return true;
  49. }
  50. }
  51. return false; // not found here
  52. }
  53. ///////////////////////////////////////////////////////////////////////////////
  54. //
  55. // The functions 'get_node_range' return a pair of iterators pointing at the
  56. // range, which contains the elements of a specified node.
  57. //
  58. ///////////////////////////////////////////////////////////////////////////////
  59. namespace impl {
  60. template <typename T>
  61. inline bool
  62. get_node_range (typename tree_node<T>::const_tree_iterator const &start,
  63. parser_id node_to_search,
  64. std::pair<typename tree_node<T>::const_tree_iterator,
  65. typename tree_node<T>::const_tree_iterator> &nodes)
  66. {
  67. // look at this node first
  68. tree_node<T> const &node = *start;
  69. if (node.value.id() == node_to_search) {
  70. if (node.children.size() > 0) {
  71. // full subrange
  72. nodes.first = node.children.begin();
  73. nodes.second = node.children.end();
  74. }
  75. else {
  76. // only this node
  77. nodes.first = start;
  78. nodes.second = start;
  79. std::advance(nodes.second, 1);
  80. }
  81. return true;
  82. }
  83. // look at subnodes now
  84. if (node.children.size() > 0) {
  85. typedef typename tree_node<T>::const_tree_iterator const_tree_iterator;
  86. const_tree_iterator end = node.children.end();
  87. for (const_tree_iterator it = node.children.begin(); it != end; ++it)
  88. {
  89. if (impl::get_node_range<T>(it, node_to_search, nodes))
  90. return true;
  91. }
  92. }
  93. return false;
  94. }
  95. } // end of namespace impl
  96. template <typename T>
  97. inline bool
  98. get_node_range (tree_node<T> const &node, parser_id node_to_search,
  99. std::pair<typename tree_node<T>::const_tree_iterator,
  100. typename tree_node<T>::const_tree_iterator> &nodes)
  101. {
  102. if (node.children.size() > 0) {
  103. typedef typename tree_node<T>::const_tree_iterator const_tree_iterator;
  104. const_tree_iterator end = node.children.end();
  105. for (const_tree_iterator it = node.children.begin(); it != end; ++it)
  106. {
  107. if (impl::get_node_range<T>(it, node_to_search, nodes))
  108. return true;
  109. }
  110. }
  111. return false;
  112. }
  113. ///////////////////////////////////////////////////////////////////////////////
  114. BOOST_SPIRIT_CLASSIC_NAMESPACE_END
  115. } // namespace spirit
  116. } // namespace boost
  117. #endif