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