antlr3commontreenodestream.inl 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. namespace antlr3 {
  2. template<class ImplTraits>
  3. CommonTreeNodeStream<ImplTraits>::CommonTreeNodeStream(ANTLR_UINT32 hint)
  4. {
  5. this->init(hint);
  6. }
  7. template<class ImplTraits>
  8. void CommonTreeNodeStream<ImplTraits>::init( ANTLR_UINT32 hint )
  9. {
  10. m_root = NULL;
  11. m_adaptor = new TreeAdaptorType;
  12. // Create the node list map
  13. //
  14. if (hint == 0)
  15. hint = DEFAULT_INITIAL_BUFFER_SIZE;
  16. m_nodes.reserve( DEFAULT_INITIAL_BUFFER_SIZE );
  17. m_p = -1;
  18. m_currentNode = NULL;
  19. m_previousNode = NULL;
  20. m_currentChildIndex = 0;
  21. m_absoluteNodeIndex = 0;
  22. m_lookAhead = NULL;
  23. m_lookAheadLength = 0;
  24. m_head = 0;
  25. m_tail = 0;
  26. m_uniqueNavigationNodes = false;
  27. m_isRewriter = false;
  28. CommonTokenType* token = new CommonTokenType(CommonTokenType::TOKEN_UP);
  29. token->set_tokText( "UP" );
  30. m_UP.set_token( token );
  31. token = new CommonTokenType(CommonTokenType::TOKEN_DOWN);
  32. token->set_tokText( "DOWN" );
  33. m_DOWN.set_token( token );
  34. token = new CommonTokenType(CommonTokenType::TOKEN_EOF);
  35. token->set_tokText( "EOF" );
  36. m_EOF_NODE.set_token( token );
  37. token = new CommonTokenType(CommonTokenType::TOKEN_INVALID);
  38. token->set_tokText( "INVALID" );
  39. m_EOF_NODE.set_token( token );
  40. }
  41. template<class ImplTraits>
  42. CommonTreeNodeStream<ImplTraits>::CommonTreeNodeStream( const CommonTreeNodeStream& ctn )
  43. {
  44. m_root = ctn.m_root;
  45. m_adaptor = ctn.m_adaptor;
  46. m_nodes.reserve( DEFAULT_INITIAL_BUFFER_SIZE );
  47. m_nodeStack = ctn.m_nodeStack;
  48. m_p = -1;
  49. m_currentNode = NULL;
  50. m_previousNode = NULL;
  51. m_currentChildIndex = 0;
  52. m_absoluteNodeIndex = 0;
  53. m_lookAhead = NULL;
  54. m_lookAheadLength = 0;
  55. m_head = 0;
  56. m_tail = 0;
  57. m_uniqueNavigationNodes = false;
  58. m_isRewriter = true;
  59. m_UP.set_token( ctn.m_UP.get_token() );
  60. m_DOWN.set_token( ctn.m_DOWN.get_token() );
  61. m_EOF_NODE.set_token( ctn.m_EOF_NODE.get_token() );
  62. m_INVALID_NODE.set_token( ctn.m_INVALID_NODE.get_token() );
  63. }
  64. template<class ImplTraits>
  65. CommonTreeNodeStream<ImplTraits>::CommonTreeNodeStream( TreeTypePtr tree, ANTLR_UINT32 hint )
  66. {
  67. this->init(hint);
  68. m_root = tree;
  69. }
  70. template<class ImplTraits>
  71. CommonTreeNodeStream<ImplTraits>::~CommonTreeNodeStream()
  72. {
  73. // If this is a rewrting stream, then certain resources
  74. // belong to the originating node stream and we do not
  75. // free them here.
  76. //
  77. if ( m_isRewriter != true)
  78. {
  79. delete m_adaptor;
  80. m_nodeStack.clear();
  81. delete m_INVALID_NODE.get_token();
  82. delete m_EOF_NODE.get_token();
  83. delete m_DOWN.get_token();
  84. delete m_UP.get_token();
  85. }
  86. m_nodes.clear();
  87. }
  88. template<class ImplTraits>
  89. typename CommonTreeNodeStream<ImplTraits>::TreeTypePtr CommonTreeNodeStream<ImplTraits>::_LT(ANTLR_INT32 k)
  90. {
  91. if ( m_p == -1)
  92. {
  93. this->fillBufferRoot();
  94. }
  95. if (k < 0)
  96. {
  97. return this->LB(-k);
  98. }
  99. else if (k == 0)
  100. {
  101. return &(m_INVALID_NODE);
  102. }
  103. // k was a legitimate request,
  104. //
  105. if (( m_p + k - 1) >= (ANTLR_INT32)(m_nodes.size()))
  106. {
  107. return &(m_EOF_NODE);
  108. }
  109. return m_nodes[ m_p + k - 1 ];
  110. }
  111. template<class ImplTraits>
  112. typename CommonTreeNodeStream<ImplTraits>::TreeTypePtr CommonTreeNodeStream<ImplTraits>::getTreeSource()
  113. {
  114. return m_root;
  115. }
  116. template<class ImplTraits>
  117. typename CommonTreeNodeStream<ImplTraits>::TreeAdaptorType* CommonTreeNodeStream<ImplTraits>::getTreeAdaptor()
  118. {
  119. return m_adaptor;
  120. }
  121. template<class ImplTraits>
  122. void CommonTreeNodeStream<ImplTraits>::set_uniqueNavigationNodes(bool uniqueNavigationNodes)
  123. {
  124. m_uniqueNavigationNodes = uniqueNavigationNodes;
  125. }
  126. template<class ImplTraits>
  127. typename CommonTreeNodeStream<ImplTraits>::StringType CommonTreeNodeStream<ImplTraits>::toString()
  128. {
  129. return this->toStringSS(m_root, NULL);
  130. }
  131. template<class ImplTraits>
  132. typename CommonTreeNodeStream<ImplTraits>::StringType CommonTreeNodeStream<ImplTraits>::toStringSS(TreeTypePtr start, TreeTypePtr stop)
  133. {
  134. StringType buf;
  135. this->toStringWork(start, stop, buf);
  136. return buf;
  137. }
  138. template<class ImplTraits>
  139. void CommonTreeNodeStream<ImplTraits>::toStringWork(TreeTypePtr start, TreeTypePtr stop, StringType& str)
  140. {
  141. ANTLR_UINT32 n;
  142. ANTLR_UINT32 c;
  143. StringStreamType buf;
  144. if (!start->isNilNode() )
  145. {
  146. StringType text;
  147. text = start->toString();
  148. if (text.empty())
  149. {
  150. buf << ' ';
  151. buf << start->getType();
  152. }
  153. else
  154. buf << text;
  155. }
  156. if (start == stop)
  157. {
  158. return; /* Finished */
  159. }
  160. n = start->getChildCount();
  161. if (n > 0 && ! start->isNilNode() )
  162. {
  163. buf << ' ';
  164. buf << CommonTokenType::TOKEN_DOWN;
  165. }
  166. for (c = 0; c<n ; c++)
  167. {
  168. TreeTypePtr child;
  169. child = start->getChild(c);
  170. this->toStringWork(child, stop, buf);
  171. }
  172. if (n > 0 && ! start->isNilNode() )
  173. {
  174. buf << ' ';
  175. buf << CommonTokenType::TOKEN_UP;
  176. }
  177. str = buf.str();
  178. }
  179. template<class ImplTraits>
  180. typename CommonTreeNodeStream<ImplTraits>::TreeTypePtr CommonTreeNodeStream<ImplTraits>::get(ANTLR_INT32 k)
  181. {
  182. if( m_p == -1 )
  183. {
  184. this->fillBufferRoot();
  185. }
  186. return m_nodes[k];
  187. }
  188. template<class ImplTraits>
  189. void CommonTreeNodeStream<ImplTraits>::replaceChildren(TreeTypePtr parent,
  190. ANTLR_INT32 startChildIndex,
  191. ANTLR_INT32 stopChildIndex,
  192. TreeTypePtr t)
  193. {
  194. if (parent != NULL)
  195. {
  196. TreeAdaptorType* adaptor;
  197. adaptor = this->getTreeAdaptor();
  198. adaptor->replaceChildren(parent, startChildIndex, stopChildIndex, t);
  199. }
  200. }
  201. template<class ImplTraits>
  202. typename CommonTreeNodeStream<ImplTraits>::TreeTypePtr CommonTreeNodeStream<ImplTraits>::LB(ANTLR_INT32 k)
  203. {
  204. if ( k==0)
  205. {
  206. return &(m_INVALID_NODE);
  207. }
  208. if ( (m_p - k) < 0)
  209. {
  210. return &(m_INVALID_NODE);
  211. }
  212. return m_nodes[ m_p - k ];
  213. }
  214. template<class ImplTraits>
  215. void CommonTreeNodeStream<ImplTraits>::addNavigationNode(ANTLR_UINT32 ttype)
  216. {
  217. TreeTypePtr node;
  218. node = NULL;
  219. if (ttype == CommonTokenType::TOKEN_DOWN)
  220. {
  221. if (this->hasUniqueNavigationNodes() == true)
  222. {
  223. node = this->newDownNode();
  224. }
  225. else
  226. {
  227. node = &m_DOWN;
  228. }
  229. }
  230. else
  231. {
  232. if (this->hasUniqueNavigationNodes() == true)
  233. {
  234. node = this->newUpNode();
  235. }
  236. else
  237. {
  238. node = &m_UP;
  239. }
  240. }
  241. // Now add the node we decided upon.
  242. //
  243. m_nodes.push_back(node);
  244. }
  245. template<class ImplTraits>
  246. typename CommonTreeNodeStream<ImplTraits>::TreeTypePtr CommonTreeNodeStream<ImplTraits>::newDownNode()
  247. {
  248. TreeTypePtr dNode;
  249. CommonTokenType* token;
  250. token = new CommonTokenType(CommonTokenType::TOKEN_DOWN);
  251. token->set_tokText("DOWN");
  252. dNode = new TreeType(token);
  253. return &dNode;
  254. }
  255. template<class ImplTraits>
  256. typename CommonTreeNodeStream<ImplTraits>::TreeTypePtr CommonTreeNodeStream<ImplTraits>::newUpNode()
  257. {
  258. TreeTypePtr uNode;
  259. CommonTokenType* token;
  260. token = new CommonTokenType(CommonTokenType::TOKEN_UP);
  261. token->set_tokText("UP");
  262. uNode = new TreeType(token);
  263. return &uNode;
  264. }
  265. template<class ImplTraits>
  266. bool CommonTreeNodeStream<ImplTraits>::hasUniqueNavigationNodes() const
  267. {
  268. return m_uniqueNavigationNodes;
  269. }
  270. template<class ImplTraits>
  271. ANTLR_UINT32 CommonTreeNodeStream<ImplTraits>::getLookaheadSize()
  272. {
  273. return m_tail < m_head
  274. ? (m_lookAheadLength - m_head + m_tail)
  275. : (m_tail - m_head);
  276. }
  277. template<class ImplTraits>
  278. void CommonTreeNodeStream<ImplTraits>::push(ANTLR_INT32 index)
  279. {
  280. m_nodeStack.push(m_p); // Save current index
  281. this->seek(index);
  282. }
  283. template<class ImplTraits>
  284. ANTLR_INT32 CommonTreeNodeStream<ImplTraits>::pop()
  285. {
  286. ANTLR_INT32 retVal;
  287. retVal = m_nodeStack.top();
  288. m_nodeStack.pop();
  289. this->seek(retVal);
  290. return retVal;
  291. }
  292. template<class ImplTraits>
  293. void CommonTreeNodeStream<ImplTraits>::reset()
  294. {
  295. if ( m_p != -1)
  296. {
  297. m_p = 0;
  298. }
  299. BaseType::m_lastMarker = 0;
  300. // Free and reset the node stack only if this is not
  301. // a rewriter, which is going to reuse the originating
  302. // node streams node stack
  303. //
  304. if (m_isRewriter != true)
  305. m_nodeStack.clear();
  306. }
  307. template<class ImplTraits>
  308. void CommonTreeNodeStream<ImplTraits>::fillBufferRoot()
  309. {
  310. // Call the generic buffer routine with the root as the
  311. // argument
  312. //
  313. this->fillBuffer(m_root);
  314. m_p = 0; // Indicate we are at buffer start
  315. }
  316. template<class ImplTraits>
  317. void CommonTreeNodeStream<ImplTraits>::fillBuffer(TreeTypePtr t)
  318. {
  319. bool nilNode;
  320. ANTLR_UINT32 nCount;
  321. ANTLR_UINT32 c;
  322. nilNode = m_adaptor->isNilNode(t);
  323. // If the supplied node is not a nil (list) node then we
  324. // add in the node itself to the vector
  325. //
  326. if (nilNode == false)
  327. {
  328. m_nodes.push_back(t);
  329. }
  330. // Only add a DOWN node if the tree is not a nil tree and
  331. // the tree does have children.
  332. //
  333. nCount = t->getChildCount();
  334. if (nilNode == false && nCount>0)
  335. {
  336. this->addNavigationNode( CommonTokenType::TOKEN_DOWN);
  337. }
  338. // We always add any children the tree contains, which is
  339. // a recursive call to this function, which will cause similar
  340. // recursion and implement a depth first addition
  341. //
  342. for (c = 0; c < nCount; c++)
  343. {
  344. this->fillBuffer( m_adaptor->getChild(t, c));
  345. }
  346. // If the tree had children and was not a nil (list) node, then we
  347. // we need to add an UP node here to match the DOWN node
  348. //
  349. if (nilNode == false && nCount > 0)
  350. {
  351. this->addNavigationNode(CommonTokenType::TOKEN_UP);
  352. }
  353. }
  354. }