1ANTLR_BEGIN_NAMESPACE() 2 3template<class ImplTraits> 4ANTLR_INLINE CommonTreeAdaptor<ImplTraits>::CommonTreeAdaptor(DebuggerType*) 5{ 6} 7 8template<class ImplTraits> 9typename CommonTreeAdaptor<ImplTraits>::TreeType* CommonTreeAdaptor<ImplTraits>::nilNode() 10{ 11 return this->create(NULL); 12} 13 14template<class ImplTraits> 15typename CommonTreeAdaptor<ImplTraits>::TreeType* CommonTreeAdaptor<ImplTraits>::dupTree( TreeType* tree) 16{ 17 return this->dupTreeTT(tree, NULL); 18} 19 20template<class ImplTraits> 21typename CommonTreeAdaptor<ImplTraits>::TreeType* CommonTreeAdaptor<ImplTraits>::dupTreeTT( TreeType* t, TreeType* parent) 22{ 23 TreeType* newTree; 24 TreeType* child; 25 TreeType* newSubTree; 26 ANTLR_UINT32 n; 27 ANTLR_UINT32 i; 28 29 if (t == NULL) 30 return NULL; 31 32 newTree = t->dupNode(); 33 34 // Ensure new subtree root has parent/child index set 35 // 36 this->setChildIndex( newTree, t->getChildIndex() ); 37 this->setParent(newTree, parent); 38 n = this->getChildCount(t); 39 40 for (i=0; i < n; i++) 41 { 42 child = this->getChild(t, i); 43 newSubTree = this->dupTreeTT(child, t); 44 this->addChild(newTree, newSubTree); 45 } 46 return newTree; 47} 48 49template<class ImplTraits> 50void CommonTreeAdaptor<ImplTraits>::addChild( TreeType* t, TreeType* child) 51{ 52 if (t != NULL && child != NULL) 53 { 54 t->addChild(child); 55 } 56} 57 58template<class ImplTraits> 59void CommonTreeAdaptor<ImplTraits>::addChildToken( TreeType* t, CommonTokenType* child) 60{ 61 if (t != NULL && child != NULL) 62 { 63 this->addChild(t, this->create(child)); 64 } 65} 66 67template<class ImplTraits> 68void CommonTreeAdaptor<ImplTraits>::setParent( TreeType* child, TreeType* parent) 69{ 70 child->setParent(parent); 71} 72 73template<class ImplTraits> 74typename CommonTreeAdaptor<ImplTraits>::TreeType* CommonTreeAdaptor<ImplTraits>::getParent( TreeType* child) 75{ 76 return child->getParent(); 77} 78 79template<class ImplTraits> 80typename CommonTreeAdaptor<ImplTraits>::TreeType* CommonTreeAdaptor<ImplTraits>::errorNode( CommonTokenType* tnstream, CommonTokenType* startToken, CommonTokenType* stopToken) 81{ 82 // Use the supplied common tree node stream to get another tree from the factory 83 // TODO: Look at creating the erronode as in Java, but this is complicated by the 84 // need to track and free the memory allocated to it, so for now, we just 85 // want something in the tree that isn't a NULL pointer. 86 // 87 return this->createTypeText( CommonTokenType::TOKEN_INVALID, "Tree Error Node"); 88 89} 90 91template<class ImplTraits> 92bool CommonTreeAdaptor<ImplTraits>::isNilNode( TreeType* t) 93{ 94 return t->isNilNode(); 95} 96 97template<class ImplTraits> 98typename CommonTreeAdaptor<ImplTraits>::TreeType* CommonTreeAdaptor<ImplTraits>::becomeRoot( TreeType* newRootTree, TreeType* oldRootTree) 99{ 100 TreeType* saveRoot; 101 102 /* Protect against tree rewrites if we are in some sort of error 103 * state, but have tried to recover. In C we can end up with a null pointer 104 * for a tree that was not produced. 105 */ 106 if (newRootTree == NULL) 107 { 108 return oldRootTree; 109 } 110 111 /* root is just the new tree as is if there is no 112 * current root tree. 113 */ 114 if (oldRootTree == NULL) 115 { 116 return newRootTree; 117 } 118 119 /* Produce ^(nil real-node) 120 */ 121 if (newRootTree->isNilNode()) 122 { 123 if (newRootTree->getChildCount() > 1) 124 { 125 /* TODO: Handle tree exceptions 126 */ 127 fprintf(stderr, "More than one node as root! TODO: Create tree exception handling\n"); 128 return newRootTree; 129 } 130 131 /* The new root is the first child, keep track of the original newRoot 132 * because if it was a Nil Node, then we can reuse it now. 133 */ 134 saveRoot = newRootTree; 135 newRootTree = newRootTree->getChild(0); 136 137 // Reclaim the old nilNode() 138 // 139 saveRoot->reuse(); 140 } 141 142 /* Add old root into new root. addChild takes care of the case where oldRoot 143 * is a flat list (nill rooted tree). All children of oldroot are added to 144 * new root. 145 */ 146 newRootTree->addChild(oldRootTree); 147 148 // If the oldroot tree was a nil node, then we know at this point 149 // it has become orphaned by the rewrite logic, so we tell it to do 150 // whatever it needs to do to be reused. 151 // 152 if (oldRootTree->isNilNode()) 153 { 154 // We have taken an old Root Tree and appended all its children to the new 155 // root. In addition though it was a nil node, which means the generated code 156 // will not reuse it again, so we will reclaim it here. First we want to zero out 157 // any pointers it was carrying around. We are just the baseTree handler so we 158 // don't know necessarilly know how to do this for the real node, we just ask the tree itself 159 // to do it. 160 // 161 oldRootTree->reuse(); 162 } 163 /* Always returns new root structure 164 */ 165 return newRootTree; 166} 167 168template<class ImplTraits> 169typename CommonTreeAdaptor<ImplTraits>::TreeType* CommonTreeAdaptor<ImplTraits>::becomeRootToken(CommonTokenType* newRoot, TreeType* oldRoot) 170{ 171 return this->becomeRoot(this->create(newRoot), oldRoot); 172} 173 174template<class ImplTraits> 175typename CommonTreeAdaptor<ImplTraits>::TreeType* CommonTreeAdaptor<ImplTraits>::create( CommonTokenType* payload) 176{ 177 return new TreeType(payload); 178} 179 180template<class ImplTraits> 181typename CommonTreeAdaptor<ImplTraits>::TreeType* CommonTreeAdaptor<ImplTraits>::createTypeToken( ANTLR_UINT32 tokenType, 182 CommonTokenType* fromToken) 183{ 184 /* Create the new token 185 */ 186 fromToken = this->createTokenFromToken(fromToken); 187 188 /* Set the type of the new token to that supplied 189 */ 190 fromToken->setType(tokenType); 191 192 /* Return a new node based upon this token 193 */ 194 return this->create(fromToken); 195 196} 197 198template<class ImplTraits> 199typename CommonTreeAdaptor<ImplTraits>::TreeType* CommonTreeAdaptor<ImplTraits>::createTypeTokenText( ANTLR_UINT32 tokenType, CommonTokenType* fromToken, const ANTLR_UINT8* text) 200{ 201 /* Create the new token 202 */ 203 fromToken = this->createTokenFromToken(fromToken); 204 205 /* Set the type of the new token to that supplied 206 */ 207 fromToken->setType(tokenType); 208 209 /* Set the text of the token accordingly 210 */ 211 fromToken->setText(text); 212 213 /* Return a new node based upon this token 214 */ 215 return this->create(fromToken); 216} 217 218template<class ImplTraits> 219typename CommonTreeAdaptor<ImplTraits>::TreeType* CommonTreeAdaptor<ImplTraits>::createTypeText( ANTLR_UINT32 tokenType, const ANTLR_UINT8* text) 220{ 221 CommonTokenType* fromToken; 222 223 /* Create the new token 224 */ 225 fromToken = this->createToken(tokenType, text); 226 227 /* Return a new node based upon this token 228 */ 229 return this->create(fromToken); 230} 231 232template<class ImplTraits> 233typename CommonTreeAdaptor<ImplTraits>::TreeType* CommonTreeAdaptor<ImplTraits>::dupNode( TreeType* treeNode) 234{ 235 return (treeNode == NULL) ? NULL : treeNode->dupNode(); 236} 237 238template<class ImplTraits> 239ANTLR_UINT32 CommonTreeAdaptor<ImplTraits>::getType( TreeType* t) 240{ 241 return t->getType(); 242} 243 244template<class ImplTraits> 245typename CommonTreeAdaptor<ImplTraits>::StringType CommonTreeAdaptor<ImplTraits>::getText( TreeType* t) 246{ 247 return t->getText(); 248} 249 250template<class ImplTraits> 251typename CommonTreeAdaptor<ImplTraits>::TreeType* CommonTreeAdaptor<ImplTraits>::getChild( TreeType* t, ANTLR_UINT32 i) 252{ 253 return t->getChild(i); 254} 255 256template<class ImplTraits> 257void CommonTreeAdaptor<ImplTraits>::setChild( TreeType* t, ANTLR_UINT32 i, TreeType* child) 258{ 259 t->setChild(i, child); 260} 261 262template<class ImplTraits> 263void CommonTreeAdaptor<ImplTraits>::deleteChild( TreeType* t, ANTLR_UINT32 i) 264{ 265 t->deleteChild(i); 266} 267 268template<class ImplTraits> 269void CommonTreeAdaptor<ImplTraits>::setChildIndex( TreeType* t, ANTLR_INT32 i) 270{ 271 t->setChildIndex(i); 272} 273 274template<class ImplTraits> 275ANTLR_INT32 CommonTreeAdaptor<ImplTraits>::getChildIndex( TreeType * t) 276{ 277 return t->getChildIndex(); 278} 279 280template<class ImplTraits> 281ANTLR_UINT32 CommonTreeAdaptor<ImplTraits>::getChildCount( TreeType* t) 282{ 283 return t->getChildCount(); 284} 285 286template<class ImplTraits> 287ANTLR_UINT64 CommonTreeAdaptor<ImplTraits>::getUniqueID( TreeType* node ) 288{ 289 return reinterpret_cast<ANTLR_UINT64>(node); 290} 291 292template<class ImplTraits> 293typename CommonTreeAdaptor<ImplTraits>::CommonTokenType* 294 CommonTreeAdaptor<ImplTraits>::createToken( ANTLR_UINT32 tokenType, const ANTLR_UINT8* text) 295{ 296 CommonTokenType* newToken = new CommonTokenType; 297 298 if (newToken != NULL) 299 { 300 newToken->set_tokText( (const char*) text ); 301 newToken->setType(tokenType); 302 } 303 return newToken; 304 305} 306 307template<class ImplTraits> 308typename CommonTreeAdaptor<ImplTraits>::CommonTokenType* 309 CommonTreeAdaptor<ImplTraits>::createTokenFromToken( CommonTokenType* fromToken) 310{ 311 CommonTokenType* newToken; 312 313 newToken = new CommonTokenType; 314 315 if (newToken != NULL) 316 { 317 // Create the text using our own string factory to avoid complicating 318 // commontoken. 319 // 320 StringType text = fromToken->getText(); 321 newToken->set_tokText( text ); 322 newToken->setLine( fromToken->getLine() ); 323 newToken->setTokenIndex( fromToken->getTokenIndex() ); 324 newToken->setCharPositionInLine( fromToken->getCharPositionInLine() ); 325 newToken->setChannel( fromToken->getChannel() ); 326 newToken->setType( fromToken->getType() ); 327 } 328 329 return newToken; 330} 331 332template<class ImplTraits> 333typename CommonTreeAdaptor<ImplTraits>::CommonTokenType* 334 CommonTreeAdaptor<ImplTraits>::getToken( TreeType* t) 335{ 336 return t->getToken(); 337} 338 339template<class ImplTraits> 340void CommonTreeAdaptor<ImplTraits>::setTokenBoundaries( TreeType* t, CommonTokenType* startToken, CommonTokenType* stopToken) 341{ 342 ANTLR_MARKER start; 343 ANTLR_MARKER stop; 344 345 TreeType* ct; 346 347 if (t == NULL) 348 { 349 return; 350 } 351 352 if ( startToken != NULL) 353 { 354 start = startToken->getTokenIndex(); 355 } 356 else 357 { 358 start = 0; 359 } 360 361 if ( stopToken != NULL) 362 { 363 stop = stopToken->getTokenIndex(); 364 } 365 else 366 { 367 stop = 0; 368 } 369 370 ct = t; 371 372 ct->set_startIndex(start); 373 ct->set_stopIndex(stop); 374} 375 376template<class ImplTraits> 377ANTLR_MARKER CommonTreeAdaptor<ImplTraits>::getTokenStartIndex( TreeType* t) 378{ 379 return t->get_tokenStartIndex(); 380} 381 382template<class ImplTraits> 383ANTLR_MARKER CommonTreeAdaptor<ImplTraits>::getTokenStopIndex( TreeType* t) 384{ 385 return t->get_tokenStopIndex(); 386} 387 388template<class ImplTraits> 389typename CommonTreeAdaptor<ImplTraits>::StringType CommonTreeAdaptor<ImplTraits>::makeDot( TreeType* theTree) 390{ 391 // The string we are building up 392 // 393 StringType dotSpec; 394 char buff[64]; 395 StringType text; 396 397 dotSpec = "digraph {\n\n" 398 "\tordering=out;\n" 399 "\tranksep=.4;\n" 400 "\tbgcolor=\"lightgrey\"; node [shape=box, fixedsize=false, fontsize=12, fontname=\"Helvetica-bold\", fontcolor=\"blue\"\n" 401 "\twidth=.25, height=.25, color=\"black\", fillcolor=\"white\", style=\"filled, solid, bold\"];\n\n" 402 "\tedge [arrowsize=.5, color=\"black\", style=\"bold\"]\n\n"; 403 404 if (theTree == NULL) 405 { 406 // No tree, so create a blank spec 407 // 408 dotSpec->append("n0[label=\"EMPTY TREE\"]\n"); 409 return dotSpec; 410 } 411 412 sprintf(buff, "\tn%p[label=\"", theTree); 413 dotSpec.append(buff); 414 text = this->getText(theTree); 415 for (std::size_t j = 0; j < text.size(); j++) 416 { 417 switch(text[j]) 418 { 419 case '"': 420 dotSpec.append("\\\""); 421 break; 422 423 case '\n': 424 dotSpec.append("\\n"); 425 break; 426 427 case '\r': 428 dotSpec.append("\\r"); 429 break; 430 431 default: 432 dotSpec += text[j]; 433 break; 434 } 435 } 436 dotSpec->append("\"]\n"); 437 438 // First produce the node defintions 439 // 440 this->defineDotNodes(theTree, dotSpec); 441 dotSpec.append("\n"); 442 this->defineDotEdges(theTree, dotSpec); 443 444 // Terminate the spec 445 // 446 dotSpec.append("\n}"); 447 448 // Result 449 // 450 return dotSpec; 451} 452 453template<class ImplTraits> 454void CommonTreeAdaptor<ImplTraits>::replaceChildren( TreeType* parent, ANTLR_INT32 startChildIndex, ANTLR_INT32 stopChildIndex, TreeType* t) 455{ 456 if (parent != NULL) 457 parent->replaceChildren(startChildIndex, stopChildIndex, t); 458} 459 460template<class ImplTraits> 461CommonTreeAdaptor<ImplTraits>::~CommonTreeAdaptor() 462{ 463} 464 465template<class ImplTraits> 466void CommonTreeAdaptor<ImplTraits>::defineDotNodes(TreeType* t, const StringType& dotSpec) 467{ 468 // How many nodes are we talking about? 469 // 470 int nCount; 471 int i; 472 TreeType* child; 473 char buff[64]; 474 StringType text; 475 int j; 476 477 // Count the nodes 478 // 479 nCount = this->getChildCount(t); 480 481 if (nCount == 0) 482 { 483 // This will already have been included as a child of another node 484 // so there is nothing to add. 485 // 486 return; 487 } 488 489 // For each child of the current tree, define a node using the 490 // memory address of the node to name it 491 // 492 for (i = 0; i<nCount; i++) 493 { 494 495 // Pick up a pointer for the child 496 // 497 child = this->getChild(t, i); 498 499 // Name the node 500 // 501 sprintf(buff, "\tn%p[label=\"", child); 502 dotSpec->append(buff); 503 text = this->getText(child); 504 for (j = 0; j < text.size(); j++) 505 { 506 switch(text[j]) 507 { 508 case '"': 509 dotSpec.append("\\\""); 510 break; 511 512 case '\n': 513 dotSpec.append("\\n"); 514 break; 515 516 case '\r': 517 dotSpec.append("\\r"); 518 break; 519 520 default: 521 dotSpec += text[j]; 522 break; 523 } 524 } 525 dotSpec.append("\"]\n"); 526 527 // And now define the children of this child (if any) 528 // 529 this->defineDotNodes(child, dotSpec); 530 } 531 532 // Done 533 // 534 return; 535} 536 537template<class ImplTraits> 538void CommonTreeAdaptor<ImplTraits>::defineDotEdges(TreeType* t, const StringType& dotSpec) 539{ 540 // How many nodes are we talking about? 541 // 542 int nCount; 543 if (t == NULL) 544 { 545 // No tree, so do nothing 546 // 547 return; 548 } 549 550 // Count the nodes 551 // 552 nCount = this->getChildCount(t); 553 554 if (nCount == 0) 555 { 556 // This will already have been included as a child of another node 557 // so there is nothing to add. 558 // 559 return; 560 } 561 562 // For each child, define an edge from this parent, then process 563 // and children of this child in the same way 564 // 565 for (int i=0; i<nCount; i++) 566 { 567 TreeType* child; 568 char buff[128]; 569 StringType text; 570 571 // Next child 572 // 573 child = this->getChild(t, i); 574 575 // Create the edge relation 576 // 577 sprintf(buff, "\t\tn%p -> n%p\t\t// ", t, child); 578 579 dotSpec.append(buff); 580 581 // Document the relationship 582 // 583 text = this->getText(t); 584 for (std::size_t j = 0; j < text.size(); j++) 585 { 586 switch(text[j]) 587 { 588 case '"': 589 dotSpec.append("\\\""); 590 break; 591 592 case '\n': 593 dotSpec.append("\\n"); 594 break; 595 596 case '\r': 597 dotSpec.append("\\r"); 598 break; 599 600 default: 601 dotSpec += text[j]; 602 break; 603 } 604 } 605 606 dotSpec.append(" -> "); 607 608 text = this->getText(child); 609 for (std::size_t j = 0; j < text.size(); j++) 610 { 611 switch(text[j]) 612 { 613 case '"': 614 dotSpec.append("\\\""); 615 break; 616 617 case '\n': 618 dotSpec.append("\\n"); 619 break; 620 621 case '\r': 622 dotSpec.append("\\r"); 623 break; 624 625 default: 626 dotSpec += text[j]; 627 break; 628 } 629 } 630 dotSpec.append("\n"); 631 632 // Define edges for this child 633 // 634 this->defineDotEdges(child, dotSpec); 635 } 636 637 // Done 638 // 639 return; 640} 641 642template<class ImplTraits> 643typename CommonTreeAdaptor<ImplTraits>::TreeType* CommonTreeAdaptor<ImplTraits>::rulePostProcessing( TreeType* root) 644{ 645 TreeType* saveRoot; 646 647 // Keep track of the root we are given. If it is a nilNode, then we 648 // can reuse it rather than orphaning it! 649 // 650 saveRoot = root; 651 652 if (root != NULL && root->isNilNode()) 653 { 654 if (root->getChildCount() == 0) 655 { 656 root = NULL; 657 } 658 else if (root->getChildCount() == 1) 659 { 660 root = root->getChild(0); 661 root->setParent(NULL); 662 root->setChildIndex(-1); 663 664 // The root we were given was a nil node, wiht one child, which means it has 665 // been abandoned and would be lost in the node factory. However 666 // nodes can be flagged as resuable to prevent this terrible waste 667 // 668 saveRoot->reuse(); 669 } 670 } 671 return root; 672} 673 674template<class ImplTraits> 675DebugTreeAdaptor<ImplTraits>::DebugTreeAdaptor( DebuggerType* debugger ) 676{ 677 m_debugger = debugger; 678} 679 680template<class ImplTraits> 681void DebugTreeAdaptor<ImplTraits>::setDebugEventListener( DebuggerType* debugger) 682{ 683 m_debugger = debugger; 684} 685 686template<class ImplTraits> 687typename DebugTreeAdaptor<ImplTraits>::TreeType* DebugTreeAdaptor<ImplTraits>::nilNode() 688{ 689 TreeType* t = this->create(NULL); 690 m_debugger->createNode(t); 691 return t; 692} 693 694template<class ImplTraits> 695void DebugTreeAdaptor<ImplTraits>::addChild(TreeType* t, TreeType* child) 696{ 697 if (t != NULL && child != NULL) 698 { 699 t->addChild(child); 700 m_debugger->addChild(t, child); 701 } 702} 703 704template<class ImplTraits> 705void DebugTreeAdaptor<ImplTraits>::addChildToken(TreeType* t, CommonTokenType* child) 706{ 707 TreeType* tc; 708 if (t != NULL && child != NULL) 709 { 710 tc = this->create(child); 711 this->addChild(t, tc); 712 m_debugger->addChild(t, tc); 713 } 714} 715 716template<class ImplTraits> 717typename DebugTreeAdaptor<ImplTraits>::TreeType* DebugTreeAdaptor<ImplTraits>::becomeRoot( TreeType* newRootTree, TreeType* oldRootTree ) 718{ 719 TreeType* t; 720 t = this->becomeRoot(newRootTree, oldRootTree); 721 m_debugger->becomeRoot(newRootTree, oldRootTree); 722 return t; 723} 724 725template<class ImplTraits> 726typename DebugTreeAdaptor<ImplTraits>::TreeType* DebugTreeAdaptor<ImplTraits>::becomeRootToken(TreeType* newRoot, TreeType* oldRoot) 727{ 728 TreeType* t; 729 t = this->becomeRoot(this->create(newRoot), oldRoot); 730 m_debugger->becomeRoot(t, oldRoot); 731 return t; 732} 733 734template<class ImplTraits> 735typename DebugTreeAdaptor<ImplTraits>::TreeType* DebugTreeAdaptor<ImplTraits>::createTypeToken(ANTLR_UINT32 tokenType, CommonTokenType* fromToken) 736{ 737 TreeType* t; 738 t = this->createTypeToken(tokenType, fromToken); 739 m_debugger->createNode(t); 740 return t; 741} 742 743template<class ImplTraits> 744typename DebugTreeAdaptor<ImplTraits>::TreeType* DebugTreeAdaptor<ImplTraits>::createTypeTokenText(ANTLR_UINT32 tokenType, CommonTokenType* fromToken, ANTLR_UINT8* text) 745{ 746 TreeType* t; 747 t = this->createTypeTokenText(tokenType, fromToken, text); 748 m_debugger->createNode(t); 749 return t; 750} 751 752template<class ImplTraits> 753typename DebugTreeAdaptor<ImplTraits>::TreeType* DebugTreeAdaptor<ImplTraits>::createTypeText( ANTLR_UINT32 tokenType, ANTLR_UINT8* text) 754{ 755 TreeType* t; 756 t = this->createTypeText(tokenType, text); 757 m_debugger->createNode(t); 758 return t; 759} 760 761template<class ImplTraits> 762typename DebugTreeAdaptor<ImplTraits>::TreeType* DebugTreeAdaptor<ImplTraits>::dupTree( TreeType* tree) 763{ 764 TreeType* t; 765 766 // Call the normal dup tree mechanism first 767 // 768 t = this->dupTreeTT(tree, NULL); 769 770 // In order to tell the debugger what we have just done, we now 771 // simulate the tree building mechanism. THis will fire 772 // lots of debugging events to the client and look like we 773 // duped the tree.. 774 // 775 this->simulateTreeConstruction( t); 776 777 return t; 778} 779 780template<class ImplTraits> 781void DebugTreeAdaptor<ImplTraits>::simulateTreeConstruction(TreeType* tree) 782{ 783 ANTLR_UINT32 n; 784 ANTLR_UINT32 i; 785 TreeType* child; 786 787 // Send the create node event 788 // 789 m_debugger->createNode(tree); 790 791 n = this->getChildCount(tree); 792 for (i = 0; i < n; i++) 793 { 794 child = this->getChild(tree, i); 795 this->simulateTreeConstruction(child); 796 m_debugger->addChild(tree, child); 797 } 798} 799 800 801ANTLR_END_NAMESPACE() 802