1ANTLR_BEGIN_NAMESPACE() 2 3template<class ImplTraits> 4CommonTree<ImplTraits>::CommonTree() 5{ 6 m_savedIndex = 0; 7 m_startIndex = 0; 8 m_stopIndex = 0; 9 m_token = NULL; 10 m_parent = NULL; 11 m_childIndex = 0; 12} 13 14template<class ImplTraits> 15CommonTree<ImplTraits>::CommonTree( const CommonTree& ctree ) 16 :m_children( ctree.m_children) 17{ 18 m_savedIndex = ctree.m_savedIndex; 19 m_startIndex = ctree.m_startIndex; 20 m_stopIndex = ctree.m_stopIndex; 21 m_token = ctree.m_token; 22 m_parent = ctree.m_parent; 23 m_childIndex = ctree.m_childIndex; 24} 25 26template<class ImplTraits> 27CommonTree<ImplTraits>::CommonTree( CommonTokenType* token ) 28{ 29 m_savedIndex = 0; 30 m_startIndex = 0; 31 m_stopIndex = 0; 32 m_token = token; 33 m_parent = NULL; 34 m_childIndex = 0; 35} 36 37template<class ImplTraits> 38CommonTree<ImplTraits>::CommonTree( CommonTree* tree ) 39{ 40 m_savedIndex = 0; 41 m_startIndex = 0; 42 m_stopIndex = 0; 43 m_token = tree->get_token(); 44 m_parent = NULL; 45 m_childIndex = 0; 46} 47 48template<class ImplTraits> 49typename CommonTree<ImplTraits>::TokenType* CommonTree<ImplTraits>::get_token() const 50{ 51 return m_token; 52} 53 54template<class ImplTraits> 55typename CommonTree<ImplTraits>::ChildrenType& CommonTree<ImplTraits>::get_children() 56{ 57 return m_children; 58} 59 60template<class ImplTraits> 61const typename CommonTree<ImplTraits>::ChildrenType& CommonTree<ImplTraits>::get_children() const 62{ 63 return m_children; 64} 65 66template<class ImplTraits> 67typename CommonTree<ImplTraits>::ChildrenType* CommonTree<ImplTraits>::get_children_p() 68{ 69 return &m_children; 70} 71 72template<class ImplTraits> 73void CommonTree<ImplTraits>::addChild(TreeType* child) 74{ 75 ANTLR_UINT32 n; 76 ANTLR_UINT32 i; 77 78 if (child == NULL) 79 return; 80 81 ChildrenType& child_children = child->get_children(); 82 ChildrenType& tree_children = this->get_children(); 83 84 if (child->isNilNode() == true) 85 { 86 if ( !child_children.empty() && child_children == tree_children ) 87 { 88 // TODO: Change to exception rather than ANTLR3_FPRINTF? 89 // 90 fprintf(stderr, "ANTLR3: An attempt was made to add a child list to itself!\n"); 91 return; 92 } 93 94 // Add all of the children's children to this list 95 // 96 if ( !child_children.empty() ) 97 { 98 if (tree_children.empty()) 99 { 100 // We are build ing the tree structure here, so we need not 101 // worry about duplication of pointers as the tree node 102 // factory will only clean up each node once. So we just 103 // copy in the child's children pointer as the child is 104 // a nil node (has not root itself). 105 // 106 tree_children.swap( child_children ); 107 this->freshenPACIndexesAll(); 108 } 109 else 110 { 111 // Need to copy the children 112 // 113 n = child_children.size(); 114 115 for (i = 0; i < n; i++) 116 { 117 TreeType* entry; 118 entry = child_children[i]; 119 120 // ANTLR3 lists can be sparse, unlike Array Lists 121 // 122 if (entry != NULL) 123 { 124 tree_children.push_back(entry); 125 } 126 } 127 } 128 } 129 } 130 else 131 { 132 // Tree we are adding is not a Nil and might have children to copy 133 // 134 if (tree_children.empty()) 135 { 136 // No children in the tree we are adding to, so create a new list on 137 // the fly to hold them. 138 // 139 this->createChildrenList(); 140 } 141 tree_children.push_back( child ); 142 } 143} 144 145template<class ImplTraits> 146void CommonTree<ImplTraits>::addChildren(const ChildListType& kids) 147{ 148 for( typename ChildListType::const_iterator iter = kids.begin(); 149 iter != kids.end(); ++iter ) 150 { 151 this->addChild( *iter ); 152 } 153} 154 155//dummy one, as vector is always there 156template<class ImplTraits> 157void CommonTree<ImplTraits>::createChildrenList() 158{ 159} 160 161template<class ImplTraits> 162typename CommonTree<ImplTraits>::TreeType* CommonTree<ImplTraits>::deleteChild(ANTLR_UINT32 i) 163{ 164 if( m_children.empty() ) 165 return NULL; 166 167 return m_children.erase( m_children.begin() + i); 168} 169 170template<class ImplTraits> 171void CommonTree<ImplTraits>::replaceChildren(ANTLR_INT32 startChildIndex, ANTLR_INT32 stopChildIndex, TreeType* newTree) 172{ 173 ANTLR_INT32 replacingHowMany; // How many nodes will go away 174 ANTLR_INT32 replacingWithHowMany; // How many nodes will replace them 175 ANTLR_INT32 numNewChildren; // Tracking variable 176 ANTLR_INT32 delta; // Difference in new vs existing count 177 178 ANTLR_INT32 i; 179 ANTLR_INT32 j; 180 181 if ( m_children.empty() ) 182 { 183 fprintf(stderr, "replaceChildren call: Indexes are invalid; no children in list for %s", this->getText().c_str() ); 184 return; 185 } 186 187 // Either use the existing list of children in the supplied nil node, or build a vector of the 188 // tree we were given if it is not a nil node, then we treat both situations exactly the same 189 // 190 ChildrenType newChildren_temp; 191 ChildrenType* newChildren; // Iterator for whatever we are going to add in 192 193 if (newTree->isNilNode()) 194 { 195 newChildren = newTree->get_children_p(); 196 } 197 else 198 { 199 newChildren = &newChildren_temp; 200 newChildren->push_back(newTree); 201 } 202 203 // Initialize 204 // 205 replacingHowMany = stopChildIndex - startChildIndex + 1; 206 replacingWithHowMany = newChildren->size(); 207 delta = replacingHowMany - replacingWithHowMany; 208 numNewChildren = newChildren->size(); 209 210 // If it is the same number of nodes, then do a direct replacement 211 // 212 if (delta == 0) 213 { 214 TreeType* child; 215 216 // Same number of nodes 217 // 218 j = 0; 219 for (i = startChildIndex; i <= stopChildIndex; i++) 220 { 221 child = newChildren->at(j); 222 ChildrenType& parent_children = this->get_children(); 223 parent_children[i] = child; 224 child->setParent(this); 225 child->setChildIndex(i); 226 } 227 } 228 else if (delta > 0) 229 { 230 ANTLR_UINT32 indexToDelete; 231 232 // Less nodes than there were before 233 // reuse what we have then delete the rest 234 // 235 ChildrenType& parent_children = this->get_children(); 236 for (j = 0; j < numNewChildren; j++) 237 { 238 parent_children[ startChildIndex + j ] = newChildren->at(j); 239 } 240 241 // We just delete the same index position until done 242 // 243 indexToDelete = startChildIndex + numNewChildren; 244 245 for (j = indexToDelete; j <= stopChildIndex; j++) 246 { 247 parent_children.erase( parent_children.begin() + indexToDelete); 248 } 249 250 this->freshenPACIndexes(startChildIndex); 251 } 252 else 253 { 254 ChildrenType& parent_children = this->get_children(); 255 ANTLR_UINT32 numToInsert; 256 257 // More nodes than there were before 258 // Use what we can, then start adding 259 // 260 for (j = 0; j < replacingHowMany; j++) 261 { 262 parent_children[ startChildIndex + j ] = newChildren->at(j); 263 } 264 265 numToInsert = replacingWithHowMany - replacingHowMany; 266 267 for (j = replacingHowMany; j < replacingWithHowMany; j++) 268 { 269 parent_children.push_back( newChildren->at(j) ); 270 } 271 272 this->freshenPACIndexes(startChildIndex); 273 } 274} 275 276template<class ImplTraits> 277CommonTree<ImplTraits>* CommonTree<ImplTraits>::dupNode() const 278{ 279 // The node we are duplicating is in fact the common tree (that's why we are here) 280 // so we use the super pointer to duplicate. 281 // 282 TreeType* clone = new TreeType(); 283 284 // The pointer we return is the base implementation of course 285 // 286 clone->set_token( m_token ); 287 return clone; 288} 289 290template<class ImplTraits> 291typename CommonTree<ImplTraits>::TreeType* CommonTree<ImplTraits>::dupTree() 292{ 293 TreeType* newTree; 294 ANTLR_UINT32 i; 295 ANTLR_UINT32 s; 296 297 newTree = this->dupNode(); 298 299 if ( !m_children.empty() ) 300 { 301 s = m_children.size(); 302 303 for (i = 0; i < s; i++) 304 { 305 TreeType* t; 306 TreeType* newNode; 307 308 t = m_children[i]; 309 310 if (t!= NULL) 311 { 312 newNode = t->dupTree(); 313 newTree->addChild(newNode); 314 } 315 } 316 } 317 318 return newTree; 319} 320 321template<class ImplTraits> 322ANTLR_UINT32 CommonTree<ImplTraits>::getCharPositionInLine() 323{ 324 CommonTokenType* token; 325 token = m_token; 326 327 if (token == NULL || (token->getCharPositionInLine() == -1) ) 328 { 329 if (this->getChildCount() > 0) 330 { 331 TreeType* child; 332 333 child = this->getChild(0); 334 335 return child->getCharPositionInLine(); 336 } 337 return 0; 338 } 339 return token->getCharPositionInLine(); 340} 341 342template<class ImplTraits> 343typename CommonTree<ImplTraits>::TreeType* CommonTree<ImplTraits>::getChild(ANTLR_UINT32 i) 344{ 345 if ( m_children.empty() 346 || i >= m_children.size() ) 347 { 348 return NULL; 349 } 350 return m_children[i]; 351 352} 353 354template<class ImplTraits> 355void CommonTree<ImplTraits>::set_childIndex( ANTLR_INT32 i) 356{ 357 m_childIndex = i; 358} 359 360template<class ImplTraits> 361ANTLR_INT32 CommonTree<ImplTraits>::get_childIndex() const 362{ 363 return m_childIndex; 364} 365 366template<class ImplTraits> 367ANTLR_UINT32 CommonTree<ImplTraits>::getChildCount() const 368{ 369 return static_cast<ANTLR_UINT32>( m_children.size() ); 370} 371 372template<class ImplTraits> 373typename CommonTree<ImplTraits>::TreeType* CommonTree<ImplTraits>::get_parent() const 374{ 375 return m_parent; 376} 377 378template<class ImplTraits> 379void CommonTree<ImplTraits>::set_parent( TreeType* parent) 380{ 381 m_parent = parent; 382} 383 384template<class ImplTraits> 385ANTLR_UINT32 CommonTree<ImplTraits>::getType() 386{ 387 if (this == NULL) 388 { 389 return 0; 390 } 391 else 392 { 393 return m_token->getType(); 394 } 395} 396 397template<class ImplTraits> 398typename CommonTree<ImplTraits>::TreeType* CommonTree<ImplTraits>::getFirstChildWithType(ANTLR_UINT32 type) 399{ 400 ANTLR_UINT32 i; 401 std::size_t cs; 402 403 TreeType* t; 404 if ( !m_children.empty() ) 405 { 406 cs = m_children.size(); 407 for (i = 0; i < cs; i++) 408 { 409 t = m_children[i]; 410 if (t->getType() == type) 411 { 412 return t; 413 } 414 } 415 } 416 return NULL; 417} 418 419template<class ImplTraits> 420ANTLR_UINT32 CommonTree<ImplTraits>::getLine() 421{ 422 TreeType* cTree = this; 423 CommonTokenType* token; 424 token = cTree->get_token(); 425 426 if (token == NULL || token->getLine() == 0) 427 { 428 if ( this->getChildCount() > 0) 429 { 430 TreeType* child; 431 child = this->getChild(0); 432 return child->getLine(); 433 } 434 return 0; 435 } 436 return token->getLine(); 437} 438 439template<class ImplTraits> 440typename CommonTree<ImplTraits>::StringType CommonTree<ImplTraits>::getText() 441{ 442 return this->toString(); 443} 444 445template<class ImplTraits> 446bool CommonTree<ImplTraits>::isNilNode() 447{ 448 // This is a Nil tree if it has no payload (Token in our case) 449 // 450 if(m_token == NULL) 451 { 452 return true; 453 } 454 else 455 { 456 return false; 457 } 458} 459 460template<class ImplTraits> 461void CommonTree<ImplTraits>::setChild(ANTLR_UINT32 i, TreeType* child) 462{ 463 if( m_children.size() >= i ) 464 m_children.resize(i+1); 465 m_children[i] = child; 466} 467 468template<class ImplTraits> 469typename CommonTree<ImplTraits>::StringType CommonTree<ImplTraits>::toStringTree() 470{ 471 StringType string; 472 ANTLR_UINT32 i; 473 ANTLR_UINT32 n; 474 TreeType* t; 475 476 if( m_children.empty() ) 477 { 478 return this->toString(); 479 } 480 481 /* Need a new string with nothing at all in it. 482 */ 483 if (this->isNilNode() == false) 484 { 485 string.append("("); 486 string.append(this->toString()); 487 string.append(" "); 488 } 489 if ( m_children != NULL) 490 { 491 n = m_children.size(); 492 493 for (i = 0; i < n; i++) 494 { 495 t = m_children[i]; 496 497 if (i > 0) 498 { 499 string.append(" "); 500 } 501 string.append(t->toStringTree()); 502 } 503 } 504 if (this->isNilNode() == false) 505 { 506 string.append(")"); 507 } 508 509 return string; 510} 511 512template<class ImplTraits> 513typename CommonTree<ImplTraits>::StringType CommonTree<ImplTraits>::toString() 514{ 515 if (this->isNilNode() ) 516 { 517 StringType nilNode; 518 519 nilNode = "nil"; 520 521 return nilNode; 522 } 523 524 return m_token->getText(); 525} 526 527template<class ImplTraits> 528void CommonTree<ImplTraits>::freshenPACIndexesAll() 529{ 530 this->freshenPACIndexes(0); 531} 532 533template<class ImplTraits> 534void CommonTree<ImplTraits>::freshenPACIndexes(ANTLR_UINT32 offset) 535{ 536 ANTLR_UINT32 count; 537 ANTLR_UINT32 c; 538 539 count = this->getChildCount(); // How many children do we have 540 541 // Loop from the supplied index and set the indexes and parent 542 // 543 for (c = offset; c < count; c++) 544 { 545 TreeType* child; 546 547 child = this->getChild(c); 548 549 child->setChildIndex(c); 550 child->setParent(this); 551 } 552} 553 554template<class ImplTraits> 555void CommonTree<ImplTraits>::reuse() 556{ 557 delete this; //memory re-use should be taken by the library user 558} 559 560template<class ImplTraits> 561CommonTree<ImplTraits>::~CommonTree() 562{ 563} 564 565ANTLR_END_NAMESPACE() 566