antlr3rewriterulesubtreestream.inl 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. namespace antlr3 {
  2. template<class ImplTraits>
  3. RewriteRuleSubtreeStream<ImplTraits>::RewriteRuleSubtreeStream(TreeAdaptorType* adaptor, const char* description)
  4. : m_adaptor(adaptor)
  5. , m_elementDescription(description)
  6. , m_dirty(false)
  7. {
  8. m_cursor = m_elements.begin();
  9. }
  10. template<class ImplTraits>
  11. RewriteRuleSubtreeStream<ImplTraits>::RewriteRuleSubtreeStream(TreeAdaptorType* adaptor, const char* description,
  12. TreeType* oneElement
  13. )
  14. : m_adaptor(adaptor)
  15. , m_elementDescription(description)
  16. , m_dirty(false)
  17. {
  18. if( oneElement != NULL )
  19. {
  20. auto tree_clone = this->dup(oneElement);
  21. this->add( tree_clone );
  22. }
  23. m_cursor = m_elements.begin();
  24. }
  25. template<class ImplTraits>
  26. RewriteRuleSubtreeStream<ImplTraits>::RewriteRuleSubtreeStream(TreeAdaptorType* adaptor, const char* description,
  27. TreeTypePtr& oneElement
  28. )
  29. : m_adaptor(adaptor)
  30. , m_elementDescription(description)
  31. , m_dirty(false)
  32. {
  33. if( oneElement != NULL )
  34. this->add( oneElement );
  35. m_cursor = m_elements.begin();
  36. }
  37. template<class ImplTraits>
  38. RewriteRuleSubtreeStream<ImplTraits>::RewriteRuleSubtreeStream(TreeAdaptorType* adaptor, const char* description,
  39. const ElementsType& elements
  40. )
  41. : m_adaptor(adaptor)
  42. , m_elementDescription(description)
  43. , m_dirty(false)
  44. , m_elements(elements)
  45. {
  46. m_cursor = m_elements.begin();
  47. }
  48. template<class ImplTraits>
  49. void
  50. RewriteRuleSubtreeStream<ImplTraits>::reset()
  51. {
  52. m_cursor = m_elements.begin();
  53. m_dirty = true;
  54. }
  55. template<class ImplTraits>
  56. void
  57. RewriteRuleSubtreeStream<ImplTraits>::add(TreeTypePtr& el)
  58. {
  59. if ( el == NULL )
  60. return;
  61. m_elements.push_back(std::move(el));
  62. m_cursor = m_elements.begin();
  63. }
  64. template<class ImplTraits>
  65. typename RewriteRuleSubtreeStream<ImplTraits>::ElementsType::iterator
  66. RewriteRuleSubtreeStream<ImplTraits>::_next()
  67. {
  68. if (m_elements.empty())
  69. {
  70. // This means that the stream is empty
  71. // Caller must cope with this (TODO throw RewriteEmptyStreamException)
  72. return m_elements.end();
  73. }
  74. if (m_dirty || m_cursor == m_elements.end())
  75. {
  76. if( m_elements.size() == 1)
  77. {
  78. // Special case when size is single element, it will just dup a lot
  79. return m_elements.begin();
  80. }
  81. // Out of elements and the size is not 1, so we cannot assume
  82. // that we just duplicate the entry n times (such as ID ent+ -> ^(ID ent)+)
  83. // This means we ran out of elements earlier than was expected.
  84. //
  85. return m_elements.end(); // Caller must cope with this (TODO throw RewriteEmptyStreamException)
  86. }
  87. // More than just a single element so we extract it from the
  88. // vector.
  89. return m_cursor++;
  90. }
  91. template<class ImplTraits>
  92. typename RewriteRuleSubtreeStream<ImplTraits>::TreeTypePtr
  93. RewriteRuleSubtreeStream<ImplTraits>::nextTree()
  94. {
  95. if ( m_dirty || ( m_cursor == m_elements.end() && m_elements.size() == 1 ))
  96. {
  97. // if out of elements and size is 1, dup
  98. typename ElementsType::iterator el = this->_next();
  99. return this->dup(*el);
  100. }
  101. // test size above then fetch
  102. typename ElementsType::iterator el = this->_next();
  103. return std::move(*el);
  104. }
  105. /*
  106. template<class ImplTraits, class SuperType>
  107. typename RewriteRuleSubtreeStream<ImplTraits, SuperType>::TokenType*
  108. RewriteRuleSubtreeStream<ImplTraits, SuperType>::nextToken()
  109. {
  110. return this->_next();
  111. }
  112. template<class ImplTraits, class SuperType>
  113. typename RewriteRuleSubtreeStream<ImplTraits, SuperType>::TokenType*
  114. RewriteRuleSubtreeStream<ImplTraits, SuperType>::next()
  115. {
  116. ANTLR_UINT32 s;
  117. s = this->size();
  118. if ( (m_cursor >= s) && (s == 1) )
  119. {
  120. TreeTypePtr el;
  121. el = this->_next();
  122. return this->dup(el);
  123. }
  124. return this->_next();
  125. }
  126. */
  127. template<class ImplTraits>
  128. typename RewriteRuleSubtreeStream<ImplTraits>::TreeTypePtr
  129. RewriteRuleSubtreeStream<ImplTraits>::dup(const TreeTypePtr& element)
  130. {
  131. return this->dupTree(element);
  132. }
  133. template<class ImplTraits>
  134. typename RewriteRuleSubtreeStream<ImplTraits>::TreeTypePtr
  135. RewriteRuleSubtreeStream<ImplTraits>::dup(const TreeType* element)
  136. {
  137. return std::move(this->dupTree(element));
  138. }
  139. template<class ImplTraits>
  140. typename RewriteRuleSubtreeStream<ImplTraits>::TreeTypePtr
  141. RewriteRuleSubtreeStream<ImplTraits>::dupTree(const TreeTypePtr& element)
  142. {
  143. return std::move(m_adaptor->dupTree(element));
  144. }
  145. template<class ImplTraits>
  146. typename RewriteRuleSubtreeStream<ImplTraits>::TreeTypePtr
  147. RewriteRuleSubtreeStream<ImplTraits>::dupTree(const TreeType* element)
  148. {
  149. return std::move(m_adaptor->dupTree(element));
  150. }
  151. template<class ImplTraits>
  152. typename RewriteRuleSubtreeStream<ImplTraits>::ElementType*
  153. RewriteRuleSubtreeStream<ImplTraits>::toTree( ElementType* element)
  154. {
  155. return element;
  156. }
  157. template<class ImplTraits>
  158. bool RewriteRuleSubtreeStream<ImplTraits>::hasNext()
  159. {
  160. return m_cursor != m_elements.end();
  161. }
  162. /// Number of elements available in the stream
  163. ///
  164. template<class ImplTraits>
  165. ANTLR_UINT32 RewriteRuleSubtreeStream<ImplTraits>::size()
  166. {
  167. return (ANTLR_UINT32)(m_elements.size());
  168. }
  169. template<class ImplTraits>
  170. typename RewriteRuleSubtreeStream<ImplTraits>::StringType
  171. RewriteRuleSubtreeStream<ImplTraits>::getDescription()
  172. {
  173. if ( m_elementDescription.empty() )
  174. {
  175. m_elementDescription = "<unknown source>";
  176. }
  177. return m_elementDescription;
  178. }
  179. template<class ImplTraits>
  180. RewriteRuleSubtreeStream<ImplTraits>::~RewriteRuleSubtreeStream()
  181. {
  182. // Before placing the stream back in the pool, we
  183. // need to clear any vector it has.
  184. m_elements.clear();
  185. }
  186. template<class ImplTraits>
  187. typename RewriteRuleSubtreeStream<ImplTraits>::TreeTypePtr
  188. RewriteRuleSubtreeStream<ImplTraits>::nextNode()
  189. {
  190. //System.out.println("nextNode: elements="+elements+", singleElement="+((Tree)singleElement).toStringTree());
  191. //ANTLR_UINT32 n = this->size();
  192. if (m_dirty || (m_cursor == m_elements.end() && m_elements.size() == 1)) {
  193. // if out of elements and size is 1, dup (at most a single node
  194. // since this is for making root nodes).
  195. typename ElementsType::iterator el = this->_next();
  196. return m_adaptor->dupNode(*el);
  197. }
  198. typename ElementsType::iterator el = this->_next();
  199. //while (m_adaptor->isNilNode(el) && m_adaptor->getChildCount(el) == 1)
  200. // tree = m_adaptor->getChild(tree, 0);
  201. TreeTypePtr& node = leftestNode(*el);
  202. //System.out.println("_next="+((Tree)tree).toStringTree());
  203. return m_adaptor->dupNode(node); // dup just the root (want node here)
  204. }
  205. template<class ImplTraits>
  206. ANTLR_INLINE
  207. typename RewriteRuleSubtreeStream<ImplTraits>::TreeTypePtr&
  208. RewriteRuleSubtreeStream<ImplTraits>::leftestNode(TreeTypePtr& node) const
  209. {
  210. if(m_adaptor->isNilNode(node) && m_adaptor->getChildCount(node) == 1)
  211. return leftestNode(node->getChild(0));
  212. else
  213. return node;
  214. }
  215. }