ANTLR_BEGIN_NAMESPACE() template ANTLR_INLINE CommonTreeAdaptor::CommonTreeAdaptor(DebuggerType*) { } template typename CommonTreeAdaptor::TreeType* CommonTreeAdaptor::nilNode() { return this->create(NULL); } template typename CommonTreeAdaptor::TreeType* CommonTreeAdaptor::dupTree( TreeType* tree) { return this->dupTreeTT(tree, NULL); } template typename CommonTreeAdaptor::TreeType* CommonTreeAdaptor::dupTreeTT( TreeType* t, TreeType* parent) { TreeType* newTree; TreeType* child; TreeType* newSubTree; ANTLR_UINT32 n; ANTLR_UINT32 i; if (t == NULL) return NULL; newTree = t->dupNode(); // Ensure new subtree root has parent/child index set // this->setChildIndex( newTree, t->getChildIndex() ); this->setParent(newTree, parent); n = this->getChildCount(t); for (i=0; i < n; i++) { child = this->getChild(t, i); newSubTree = this->dupTreeTT(child, t); this->addChild(newTree, newSubTree); } return newTree; } template void CommonTreeAdaptor::addChild( TreeType* t, TreeType* child) { if (t != NULL && child != NULL) { t->addChild(child); } } template void CommonTreeAdaptor::addChildToken( TreeType* t, CommonTokenType* child) { if (t != NULL && child != NULL) { this->addChild(t, this->create(child)); } } template void CommonTreeAdaptor::setParent( TreeType* child, TreeType* parent) { child->setParent(parent); } template typename CommonTreeAdaptor::TreeType* CommonTreeAdaptor::getParent( TreeType* child) { return child->getParent(); } template typename CommonTreeAdaptor::TreeType* CommonTreeAdaptor::errorNode( CommonTokenType* tnstream, CommonTokenType* startToken, CommonTokenType* stopToken) { // Use the supplied common tree node stream to get another tree from the factory // TODO: Look at creating the erronode as in Java, but this is complicated by the // need to track and free the memory allocated to it, so for now, we just // want something in the tree that isn't a NULL pointer. // return this->createTypeText( CommonTokenType::TOKEN_INVALID, "Tree Error Node"); } template bool CommonTreeAdaptor::isNilNode( TreeType* t) { return t->isNilNode(); } template typename CommonTreeAdaptor::TreeType* CommonTreeAdaptor::becomeRoot( TreeType* newRootTree, TreeType* oldRootTree) { TreeType* saveRoot; /* Protect against tree rewrites if we are in some sort of error * state, but have tried to recover. In C we can end up with a null pointer * for a tree that was not produced. */ if (newRootTree == NULL) { return oldRootTree; } /* root is just the new tree as is if there is no * current root tree. */ if (oldRootTree == NULL) { return newRootTree; } /* Produce ^(nil real-node) */ if (newRootTree->isNilNode()) { if (newRootTree->getChildCount() > 1) { /* TODO: Handle tree exceptions */ fprintf(stderr, "More than one node as root! TODO: Create tree exception handling\n"); return newRootTree; } /* The new root is the first child, keep track of the original newRoot * because if it was a Nil Node, then we can reuse it now. */ saveRoot = newRootTree; newRootTree = newRootTree->getChild(0); // Reclaim the old nilNode() // saveRoot->reuse(); } /* Add old root into new root. addChild takes care of the case where oldRoot * is a flat list (nill rooted tree). All children of oldroot are added to * new root. */ newRootTree->addChild(oldRootTree); // If the oldroot tree was a nil node, then we know at this point // it has become orphaned by the rewrite logic, so we tell it to do // whatever it needs to do to be reused. // if (oldRootTree->isNilNode()) { // We have taken an old Root Tree and appended all its children to the new // root. In addition though it was a nil node, which means the generated code // will not reuse it again, so we will reclaim it here. First we want to zero out // any pointers it was carrying around. We are just the baseTree handler so we // don't know necessarilly know how to do this for the real node, we just ask the tree itself // to do it. // oldRootTree->reuse(); } /* Always returns new root structure */ return newRootTree; } template typename CommonTreeAdaptor::TreeType* CommonTreeAdaptor::becomeRootToken(CommonTokenType* newRoot, TreeType* oldRoot) { return this->becomeRoot(this->create(newRoot), oldRoot); } template typename CommonTreeAdaptor::TreeType* CommonTreeAdaptor::create( CommonTokenType* payload) { return new TreeType(payload); } template typename CommonTreeAdaptor::TreeType* CommonTreeAdaptor::createTypeToken( ANTLR_UINT32 tokenType, CommonTokenType* fromToken) { /* Create the new token */ fromToken = this->createTokenFromToken(fromToken); /* Set the type of the new token to that supplied */ fromToken->setType(tokenType); /* Return a new node based upon this token */ return this->create(fromToken); } template typename CommonTreeAdaptor::TreeType* CommonTreeAdaptor::createTypeTokenText( ANTLR_UINT32 tokenType, CommonTokenType* fromToken, const ANTLR_UINT8* text) { /* Create the new token */ fromToken = this->createTokenFromToken(fromToken); /* Set the type of the new token to that supplied */ fromToken->setType(tokenType); /* Set the text of the token accordingly */ fromToken->setText(text); /* Return a new node based upon this token */ return this->create(fromToken); } template typename CommonTreeAdaptor::TreeType* CommonTreeAdaptor::createTypeText( ANTLR_UINT32 tokenType, const ANTLR_UINT8* text) { CommonTokenType* fromToken; /* Create the new token */ fromToken = this->createToken(tokenType, text); /* Return a new node based upon this token */ return this->create(fromToken); } template typename CommonTreeAdaptor::TreeType* CommonTreeAdaptor::dupNode( TreeType* treeNode) { return (treeNode == NULL) ? NULL : treeNode->dupNode(); } template ANTLR_UINT32 CommonTreeAdaptor::getType( TreeType* t) { return t->getType(); } template typename CommonTreeAdaptor::StringType CommonTreeAdaptor::getText( TreeType* t) { return t->getText(); } template typename CommonTreeAdaptor::TreeType* CommonTreeAdaptor::getChild( TreeType* t, ANTLR_UINT32 i) { return t->getChild(i); } template void CommonTreeAdaptor::setChild( TreeType* t, ANTLR_UINT32 i, TreeType* child) { t->setChild(i, child); } template void CommonTreeAdaptor::deleteChild( TreeType* t, ANTLR_UINT32 i) { t->deleteChild(i); } template void CommonTreeAdaptor::setChildIndex( TreeType* t, ANTLR_INT32 i) { t->setChildIndex(i); } template ANTLR_INT32 CommonTreeAdaptor::getChildIndex( TreeType * t) { return t->getChildIndex(); } template ANTLR_UINT32 CommonTreeAdaptor::getChildCount( TreeType* t) { return t->getChildCount(); } template ANTLR_UINT64 CommonTreeAdaptor::getUniqueID( TreeType* node ) { return reinterpret_cast(node); } template typename CommonTreeAdaptor::CommonTokenType* CommonTreeAdaptor::createToken( ANTLR_UINT32 tokenType, const ANTLR_UINT8* text) { CommonTokenType* newToken = new CommonTokenType; if (newToken != NULL) { newToken->set_tokText( (const char*) text ); newToken->setType(tokenType); } return newToken; } template typename CommonTreeAdaptor::CommonTokenType* CommonTreeAdaptor::createTokenFromToken( CommonTokenType* fromToken) { CommonTokenType* newToken; newToken = new CommonTokenType; if (newToken != NULL) { // Create the text using our own string factory to avoid complicating // commontoken. // StringType text = fromToken->getText(); newToken->set_tokText( text ); newToken->setLine( fromToken->getLine() ); newToken->setTokenIndex( fromToken->getTokenIndex() ); newToken->setCharPositionInLine( fromToken->getCharPositionInLine() ); newToken->setChannel( fromToken->getChannel() ); newToken->setType( fromToken->getType() ); } return newToken; } template typename CommonTreeAdaptor::CommonTokenType* CommonTreeAdaptor::getToken( TreeType* t) { return t->getToken(); } template void CommonTreeAdaptor::setTokenBoundaries( TreeType* t, CommonTokenType* startToken, CommonTokenType* stopToken) { ANTLR_MARKER start; ANTLR_MARKER stop; TreeType* ct; if (t == NULL) { return; } if ( startToken != NULL) { start = startToken->getTokenIndex(); } else { start = 0; } if ( stopToken != NULL) { stop = stopToken->getTokenIndex(); } else { stop = 0; } ct = t; ct->set_startIndex(start); ct->set_stopIndex(stop); } template ANTLR_MARKER CommonTreeAdaptor::getTokenStartIndex( TreeType* t) { return t->get_tokenStartIndex(); } template ANTLR_MARKER CommonTreeAdaptor::getTokenStopIndex( TreeType* t) { return t->get_tokenStopIndex(); } template typename CommonTreeAdaptor::StringType CommonTreeAdaptor::makeDot( TreeType* theTree) { // The string we are building up // StringType dotSpec; char buff[64]; StringType text; dotSpec = "digraph {\n\n" "\tordering=out;\n" "\tranksep=.4;\n" "\tbgcolor=\"lightgrey\"; node [shape=box, fixedsize=false, fontsize=12, fontname=\"Helvetica-bold\", fontcolor=\"blue\"\n" "\twidth=.25, height=.25, color=\"black\", fillcolor=\"white\", style=\"filled, solid, bold\"];\n\n" "\tedge [arrowsize=.5, color=\"black\", style=\"bold\"]\n\n"; if (theTree == NULL) { // No tree, so create a blank spec // dotSpec->append("n0[label=\"EMPTY TREE\"]\n"); return dotSpec; } sprintf(buff, "\tn%p[label=\"", theTree); dotSpec.append(buff); text = this->getText(theTree); for (std::size_t j = 0; j < text.size(); j++) { switch(text[j]) { case '"': dotSpec.append("\\\""); break; case '\n': dotSpec.append("\\n"); break; case '\r': dotSpec.append("\\r"); break; default: dotSpec += text[j]; break; } } dotSpec->append("\"]\n"); // First produce the node defintions // this->defineDotNodes(theTree, dotSpec); dotSpec.append("\n"); this->defineDotEdges(theTree, dotSpec); // Terminate the spec // dotSpec.append("\n}"); // Result // return dotSpec; } template void CommonTreeAdaptor::replaceChildren( TreeType* parent, ANTLR_INT32 startChildIndex, ANTLR_INT32 stopChildIndex, TreeType* t) { if (parent != NULL) parent->replaceChildren(startChildIndex, stopChildIndex, t); } template CommonTreeAdaptor::~CommonTreeAdaptor() { } template void CommonTreeAdaptor::defineDotNodes(TreeType* t, const StringType& dotSpec) { // How many nodes are we talking about? // int nCount; int i; TreeType* child; char buff[64]; StringType text; int j; // Count the nodes // nCount = this->getChildCount(t); if (nCount == 0) { // This will already have been included as a child of another node // so there is nothing to add. // return; } // For each child of the current tree, define a node using the // memory address of the node to name it // for (i = 0; igetChild(t, i); // Name the node // sprintf(buff, "\tn%p[label=\"", child); dotSpec->append(buff); text = this->getText(child); for (j = 0; j < text.size(); j++) { switch(text[j]) { case '"': dotSpec.append("\\\""); break; case '\n': dotSpec.append("\\n"); break; case '\r': dotSpec.append("\\r"); break; default: dotSpec += text[j]; break; } } dotSpec.append("\"]\n"); // And now define the children of this child (if any) // this->defineDotNodes(child, dotSpec); } // Done // return; } template void CommonTreeAdaptor::defineDotEdges(TreeType* t, const StringType& dotSpec) { // How many nodes are we talking about? // int nCount; if (t == NULL) { // No tree, so do nothing // return; } // Count the nodes // nCount = this->getChildCount(t); if (nCount == 0) { // This will already have been included as a child of another node // so there is nothing to add. // return; } // For each child, define an edge from this parent, then process // and children of this child in the same way // for (int i=0; igetChild(t, i); // Create the edge relation // sprintf(buff, "\t\tn%p -> n%p\t\t// ", t, child); dotSpec.append(buff); // Document the relationship // text = this->getText(t); for (std::size_t j = 0; j < text.size(); j++) { switch(text[j]) { case '"': dotSpec.append("\\\""); break; case '\n': dotSpec.append("\\n"); break; case '\r': dotSpec.append("\\r"); break; default: dotSpec += text[j]; break; } } dotSpec.append(" -> "); text = this->getText(child); for (std::size_t j = 0; j < text.size(); j++) { switch(text[j]) { case '"': dotSpec.append("\\\""); break; case '\n': dotSpec.append("\\n"); break; case '\r': dotSpec.append("\\r"); break; default: dotSpec += text[j]; break; } } dotSpec.append("\n"); // Define edges for this child // this->defineDotEdges(child, dotSpec); } // Done // return; } template typename CommonTreeAdaptor::TreeType* CommonTreeAdaptor::rulePostProcessing( TreeType* root) { TreeType* saveRoot; // Keep track of the root we are given. If it is a nilNode, then we // can reuse it rather than orphaning it! // saveRoot = root; if (root != NULL && root->isNilNode()) { if (root->getChildCount() == 0) { root = NULL; } else if (root->getChildCount() == 1) { root = root->getChild(0); root->setParent(NULL); root->setChildIndex(-1); // The root we were given was a nil node, wiht one child, which means it has // been abandoned and would be lost in the node factory. However // nodes can be flagged as resuable to prevent this terrible waste // saveRoot->reuse(); } } return root; } template DebugTreeAdaptor::DebugTreeAdaptor( DebuggerType* debugger ) { m_debugger = debugger; } template void DebugTreeAdaptor::setDebugEventListener( DebuggerType* debugger) { m_debugger = debugger; } template typename DebugTreeAdaptor::TreeType* DebugTreeAdaptor::nilNode() { TreeType* t = this->create(NULL); m_debugger->createNode(t); return t; } template void DebugTreeAdaptor::addChild(TreeType* t, TreeType* child) { if (t != NULL && child != NULL) { t->addChild(child); m_debugger->addChild(t, child); } } template void DebugTreeAdaptor::addChildToken(TreeType* t, CommonTokenType* child) { TreeType* tc; if (t != NULL && child != NULL) { tc = this->create(child); this->addChild(t, tc); m_debugger->addChild(t, tc); } } template typename DebugTreeAdaptor::TreeType* DebugTreeAdaptor::becomeRoot( TreeType* newRootTree, TreeType* oldRootTree ) { TreeType* t; t = this->becomeRoot(newRootTree, oldRootTree); m_debugger->becomeRoot(newRootTree, oldRootTree); return t; } template typename DebugTreeAdaptor::TreeType* DebugTreeAdaptor::becomeRootToken(TreeType* newRoot, TreeType* oldRoot) { TreeType* t; t = this->becomeRoot(this->create(newRoot), oldRoot); m_debugger->becomeRoot(t, oldRoot); return t; } template typename DebugTreeAdaptor::TreeType* DebugTreeAdaptor::createTypeToken(ANTLR_UINT32 tokenType, CommonTokenType* fromToken) { TreeType* t; t = this->createTypeToken(tokenType, fromToken); m_debugger->createNode(t); return t; } template typename DebugTreeAdaptor::TreeType* DebugTreeAdaptor::createTypeTokenText(ANTLR_UINT32 tokenType, CommonTokenType* fromToken, ANTLR_UINT8* text) { TreeType* t; t = this->createTypeTokenText(tokenType, fromToken, text); m_debugger->createNode(t); return t; } template typename DebugTreeAdaptor::TreeType* DebugTreeAdaptor::createTypeText( ANTLR_UINT32 tokenType, ANTLR_UINT8* text) { TreeType* t; t = this->createTypeText(tokenType, text); m_debugger->createNode(t); return t; } template typename DebugTreeAdaptor::TreeType* DebugTreeAdaptor::dupTree( TreeType* tree) { TreeType* t; // Call the normal dup tree mechanism first // t = this->dupTreeTT(tree, NULL); // In order to tell the debugger what we have just done, we now // simulate the tree building mechanism. THis will fire // lots of debugging events to the client and look like we // duped the tree.. // this->simulateTreeConstruction( t); return t; } template void DebugTreeAdaptor::simulateTreeConstruction(TreeType* tree) { ANTLR_UINT32 n; ANTLR_UINT32 i; TreeType* child; // Send the create node event // m_debugger->createNode(tree); n = this->getChildCount(tree); for (i = 0; i < n; i++) { child = this->getChild(tree, i); this->simulateTreeConstruction(child); m_debugger->addChild(tree, child); } } ANTLR_END_NAMESPACE()