antlr3commontreenodestream.hpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. /// \file
  2. /// Definition of the ANTLR3 common tree node stream.
  3. ///
  4. #ifndef _ANTLR_COMMON_TREE_NODE_STREAM__HPP
  5. #define _ANTLR_COMMON_TREE_NODE_STREAM__HPP
  6. // [The "BSD licence"]
  7. // Copyright (c) 2005-2009 Gokulakannan Somasundaram, ElectronDB
  8. //
  9. // All rights reserved.
  10. //
  11. // Redistribution and use in source and binary forms, with or without
  12. // modification, are permitted provided that the following conditions
  13. // are met:
  14. // 1. Redistributions of source code must retain the above copyright
  15. // notice, this list of conditions and the following disclaimer.
  16. // 2. Redistributions in binary form must reproduce the above copyright
  17. // notice, this list of conditions and the following disclaimer in the
  18. // documentation and/or other materials provided with the distribution.
  19. // 3. The name of the author may not be used to endorse or promote products
  20. // derived from this software without specific prior written permission.
  21. //
  22. // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  23. // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  24. // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  25. // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  26. // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  27. // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  28. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  29. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  31. // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32. namespace antlr3 {
  33. template<class ImplTraits>
  34. class CommonTreeNodeStream : public ImplTraits::TreeNodeIntStreamType
  35. {
  36. public:
  37. enum Constants
  38. {
  39. /// Token buffer initial size settings ( will auto increase)
  40. ///
  41. DEFAULT_INITIAL_BUFFER_SIZE = 100
  42. , INITIAL_CALL_STACK_SIZE = 10
  43. };
  44. typedef typename ImplTraits::TreeType TreeType;
  45. typedef typename ImplTraits::TreeTypePtr TreeTypePtr;
  46. typedef TreeType UnitType;
  47. typedef typename ImplTraits::StringType StringType;
  48. typedef typename ImplTraits::StringStreamType StringStreamType;
  49. typedef typename ImplTraits::TreeAdaptorType TreeAdaptorType;
  50. typedef typename ImplTraits::TreeNodeIntStreamType IntStreamType;
  51. typedef typename ImplTraits::AllocPolicyType AllocPolicyType;
  52. typedef typename AllocPolicyType::template VectorType<TreeTypePtr> NodesType;
  53. typedef typename AllocPolicyType::template VectorType< TreeWalkState<ImplTraits> > MarkersType;
  54. typedef typename AllocPolicyType::template StackType< ANTLR_INT32 > NodeStackType;
  55. typedef typename ImplTraits::TreeParserType ComponentType;
  56. typedef typename ImplTraits::CommonTokenType CommonTokenType;
  57. typedef typename ImplTraits::TreeNodeIntStreamType BaseType;
  58. public:
  59. /// Dummy tree node that indicates a descent into a child
  60. /// tree. Initialized by a call to create a new interface.
  61. ///
  62. TreeType m_DOWN;
  63. /// Dummy tree node that indicates a descent up to a parent
  64. /// tree. Initialized by a call to create a new interface.
  65. ///
  66. TreeType m_UP;
  67. /// Dummy tree node that indicates the termination point of the
  68. /// tree. Initialized by a call to create a new interface.
  69. ///
  70. TreeType m_EOF_NODE;
  71. /// Dummy node that is returned if we need to indicate an invalid node
  72. /// for any reason.
  73. ///
  74. TreeType m_INVALID_NODE;
  75. /// The complete mapping from stream index to tree node.
  76. /// This buffer includes pointers to DOWN, UP, and EOF nodes.
  77. /// It is built upon ctor invocation. The elements are type
  78. /// Object as we don't what the trees look like.
  79. ///
  80. /// Load upon first need of the buffer so we can set token types
  81. /// of interest for reverseIndexing. Slows us down a wee bit to
  82. /// do all of the if p==-1 testing everywhere though, though in C
  83. /// you won't really be able to measure this.
  84. ///
  85. /// Must be freed when the tree node stream is torn down.
  86. ///
  87. NodesType m_nodes;
  88. /// Which tree are we navigating ?
  89. ///
  90. TreeTypePtr m_root;
  91. /// Pointer to tree adaptor interface that manipulates/builds
  92. /// the tree.
  93. ///
  94. TreeAdaptorType* m_adaptor;
  95. /// As we walk down the nodes, we must track parent nodes so we know
  96. /// where to go after walking the last child of a node. When visiting
  97. /// a child, push current node and current index (current index
  98. /// is first stored in the tree node structure to avoid two stacks.
  99. ///
  100. NodeStackType m_nodeStack;
  101. /// The current index into the nodes vector of the current tree
  102. /// we are parsing and possibly rewriting.
  103. ///
  104. ANTLR_INT32 m_p;
  105. /// Which node are we currently visiting?
  106. ///
  107. TreeTypePtr m_currentNode;
  108. /// Which node did we last visit? Used for LT(-1)
  109. ///
  110. TreeTypePtr m_previousNode;
  111. /// Which child are we currently visiting? If -1 we have not visited
  112. /// this node yet; next consume() request will set currentIndex to 0.
  113. ///
  114. ANTLR_INT32 m_currentChildIndex;
  115. /// What node index did we just consume? i=0..n-1 for n node trees.
  116. /// IntStream.next is hence 1 + this value. Size will be same.
  117. ///
  118. ANTLR_MARKER m_absoluteNodeIndex;
  119. /// Buffer tree node stream for use with LT(i). This list grows
  120. /// to fit new lookahead depths, but consume() wraps like a circular
  121. /// buffer.
  122. ///
  123. TreeTypePtr* m_lookAhead;
  124. /// Number of elements available in the lookahead buffer at any point in
  125. /// time. This is the current size of the array.
  126. ///
  127. ANTLR_UINT32 m_lookAheadLength;
  128. /// lookAhead[head] is the first symbol of lookahead, LT(1).
  129. ///
  130. ANTLR_UINT32 m_head;
  131. /// Add new lookahead at lookahead[tail]. tail wraps around at the
  132. /// end of the lookahead buffer so tail could be less than head.
  133. ///
  134. ANTLR_UINT32 m_tail;
  135. /// Calls to mark() may be nested so we have to track a stack of
  136. /// them. The marker is an index into this stack. Index 0 is
  137. /// the first marker. This is a List<TreeWalkState>
  138. ///
  139. MarkersType m_markers;
  140. /// Indicates whether this node stream was derived from a prior
  141. /// node stream to be used by a rewriting tree parser for instance.
  142. /// If this flag is set to ANTLR_TRUE, then when this stream is
  143. /// closed it will not free the root tree as this tree always
  144. /// belongs to the origniating node stream.
  145. ///
  146. bool m_isRewriter;
  147. /// If set to ANTLR_TRUE then the navigation nodes UP, DOWN are
  148. /// duplicated rather than reused within the tree.
  149. ///
  150. bool m_uniqueNavigationNodes;
  151. public:
  152. // INTERFACE
  153. //
  154. CommonTreeNodeStream( ANTLR_UINT32 hint );
  155. CommonTreeNodeStream( const CommonTreeNodeStream& ctn );
  156. CommonTreeNodeStream( TreeTypePtr tree, ANTLR_UINT32 hint );
  157. void init( ANTLR_UINT32 hint );
  158. ~CommonTreeNodeStream();
  159. /// Get tree node at current input pointer + i ahead where i=1 is next node.
  160. /// i<0 indicates nodes in the past. So LT(-1) is previous node, but
  161. /// implementations are not required to provide results for k < -1.
  162. /// LT(0) is undefined. For i>=n, return null.
  163. /// Return NULL for LT(0) and any index that results in an absolute address
  164. /// that is negative (beyond the start of the list).
  165. ///
  166. /// This is analogous to the LT() method of the TokenStream, but this
  167. /// returns a tree node instead of a token. Makes code gen identical
  168. /// for both parser and tree grammars. :)
  169. ///
  170. TreeTypePtr _LT(ANTLR_INT32 k);
  171. /// Where is this stream pulling nodes from? This is not the name, but
  172. /// the object that provides node objects.
  173. ///
  174. TreeTypePtr getTreeSource();
  175. /// What adaptor can tell me how to interpret/navigate nodes and
  176. /// trees. E.g., get text of a node.
  177. ///
  178. TreeAdaptorType* getTreeAdaptor();
  179. /// As we flatten the tree, we use UP, DOWN nodes to represent
  180. /// the tree structure. When debugging we need unique nodes
  181. /// so we have to instantiate new ones. When doing normal tree
  182. /// parsing, it's slow and a waste of memory to create unique
  183. /// navigation nodes. Default should be false;
  184. ///
  185. void set_uniqueNavigationNodes(bool uniqueNavigationNodes);
  186. StringType toString();
  187. /// Return the text of all nodes from start to stop, inclusive.
  188. /// If the stream does not buffer all the nodes then it can still
  189. /// walk recursively from start until stop. You can always return
  190. /// null or "" too, but users should not access $ruleLabel.text in
  191. /// an action of course in that case.
  192. ///
  193. StringType toStringSS(TreeTypePtr start, TreeTypePtr stop);
  194. /// Return the text of all nodes from start to stop, inclusive, into the
  195. /// supplied buffer.
  196. /// If the stream does not buffer all the nodes then it can still
  197. /// walk recursively from start until stop. You can always return
  198. /// null or "" too, but users should not access $ruleLabel.text in
  199. /// an action of course in that case.
  200. ///
  201. void toStringWork(TreeTypePtr start, TreeTypePtr stop, StringType& buf);
  202. /// Get a tree node at an absolute index i; 0..n-1.
  203. /// If you don't want to buffer up nodes, then this method makes no
  204. /// sense for you.
  205. ///
  206. TreeTypePtr get(ANTLR_INT32 i);
  207. // REWRITING TREES (used by tree parser)
  208. /// Replace from start to stop child index of parent with t, which might
  209. /// be a list. Number of children may be different
  210. /// after this call. The stream is notified because it is walking the
  211. /// tree and might need to know you are monkeying with the underlying
  212. /// tree. Also, it might be able to modify the node stream to avoid
  213. /// restreaming for future phases.
  214. ///
  215. /// If parent is null, don't do anything; must be at root of overall tree.
  216. /// Can't replace whatever points to the parent externally. Do nothing.
  217. ///
  218. void replaceChildren(TreeTypePtr parent, ANTLR_INT32 startChildIndex,
  219. ANTLR_INT32 stopChildIndex, TreeTypePtr t);
  220. TreeTypePtr LB(ANTLR_INT32 k);
  221. /// As we flatten the tree, we use UP, DOWN nodes to represent
  222. /// the tree structure. When debugging we need unique nodes
  223. /// so instantiate new ones when uniqueNavigationNodes is true.
  224. ///
  225. void addNavigationNode(ANTLR_UINT32 ttype);
  226. TreeTypePtr newDownNode();
  227. TreeTypePtr newUpNode();
  228. bool hasUniqueNavigationNodes() const;
  229. ANTLR_UINT32 getLookaheadSize();
  230. void push(ANTLR_INT32 index);
  231. ANTLR_INT32 pop();
  232. void reset();
  233. void fillBufferRoot();
  234. void fillBuffer(TreeTypePtr t);
  235. };
  236. /** This structure is used to save the state information in the treenodestream
  237. * when walking ahead with cyclic DFA or for syntactic predicates,
  238. * we need to record the state of the tree node stream. This
  239. * class wraps up the current state of the CommonTreeNodeStream.
  240. * Calling mark() will push another of these on the markers stack.
  241. */
  242. template<class ImplTraits>
  243. class TreeWalkState : public ImplTraits::AllocPolicyType
  244. {
  245. public:
  246. typedef typename ImplTraits::TreeType TreeType;
  247. typedef typename ImplTraits::TreeTypePtr TreeTypePtr;
  248. private:
  249. ANTLR_UINT32 m_currentChildIndex;
  250. ANTLR_MARKER m_absoluteNodeIndex;
  251. TreeTypePtr m_currentNode;
  252. TreeTypePtr m_previousNode;
  253. ANTLR_UINT32 m_nodeStackSize;
  254. TreeTypePtr m_lookAhead;
  255. ANTLR_UINT32 m_lookAheadLength;
  256. ANTLR_UINT32 m_tail;
  257. ANTLR_UINT32 m_head;
  258. };
  259. }
  260. #include "antlr3commontreenodestream.inl"
  261. #endif