/** \file * Contains the base functions that all tree adaptors start with. * this implementation can then be overridden by any higher implementation. * */ // [The "BSD licence"] // Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC // http://www.temporal-wave.com // http://www.linkedin.com/in/jimidle // // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // 3. The name of the author may not be used to endorse or promote products // derived from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <antlr3basetreeadaptor.h> #ifdef ANTLR3_WINDOWS #pragma warning( disable : 4100 ) #endif /* Interface functions */ static pANTLR3_BASE_TREE nilNode (pANTLR3_BASE_TREE_ADAPTOR adaptor); static pANTLR3_BASE_TREE dbgNil (pANTLR3_BASE_TREE_ADAPTOR adaptor); static pANTLR3_BASE_TREE dupTree (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t); static pANTLR3_BASE_TREE dbgDupTree (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t); static pANTLR3_BASE_TREE dupTreeTT (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, pANTLR3_BASE_TREE parent); static void addChild (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, pANTLR3_BASE_TREE child); static void dbgAddChild (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, pANTLR3_BASE_TREE child); static pANTLR3_BASE_TREE becomeRoot (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE newRoot, pANTLR3_BASE_TREE oldRoot); static pANTLR3_BASE_TREE dbgBecomeRoot (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE newRoot, pANTLR3_BASE_TREE oldRoot); static pANTLR3_BASE_TREE rulePostProcessing (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE root); static void addChildToken (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, pANTLR3_COMMON_TOKEN child); static void dbgAddChildToken (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, pANTLR3_COMMON_TOKEN child); static pANTLR3_BASE_TREE becomeRootToken (pANTLR3_BASE_TREE_ADAPTOR adaptor, void * newRoot, pANTLR3_BASE_TREE oldRoot); static pANTLR3_BASE_TREE dbgBecomeRootToken (pANTLR3_BASE_TREE_ADAPTOR adaptor, void * newRoot, pANTLR3_BASE_TREE oldRoot); static pANTLR3_BASE_TREE createTypeToken (pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_COMMON_TOKEN fromToken); static pANTLR3_BASE_TREE dbgCreateTypeToken (pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_COMMON_TOKEN fromToken); static pANTLR3_BASE_TREE createTypeTokenText (pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_COMMON_TOKEN fromToken, pANTLR3_UINT8 text); static pANTLR3_BASE_TREE dbgCreateTypeTokenText (pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_COMMON_TOKEN fromToken, pANTLR3_UINT8 text); static pANTLR3_BASE_TREE createTypeText (pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_UINT8 text); static pANTLR3_BASE_TREE dbgCreateTypeText (pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_UINT8 text); static ANTLR3_UINT32 getType (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t); static void setType (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, ANTLR3_UINT32 type); static pANTLR3_STRING getText (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t); static void setText (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_STRING t); static void setText8 (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_UINT8 t); static pANTLR3_BASE_TREE getChild (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, ANTLR3_UINT32 i); static ANTLR3_UINT32 getChildCount (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t); static ANTLR3_UINT32 getUniqueID (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t); static ANTLR3_BOOLEAN isNilNode (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t); static pANTLR3_STRING makeDot (pANTLR3_BASE_TREE_ADAPTOR adaptor, void * theTree); /** Given a pointer to a base tree adaptor structure (which is usually embedded in the * super class the implements the tree adaptor used in the parse), initialize its * function pointers and so on. */ ANTLR3_API void antlr3BaseTreeAdaptorInit(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_DEBUG_EVENT_LISTENER debugger) { // Initialize the interface // if (debugger == NULL) { adaptor->nilNode = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR)) nilNode; adaptor->addChild = (void (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, void *)) addChild; adaptor->becomeRoot = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, void *)) becomeRoot; adaptor->addChildToken = (void (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, pANTLR3_COMMON_TOKEN)) addChildToken; adaptor->becomeRootToken = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, void *)) becomeRootToken; adaptor->createTypeToken = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, ANTLR3_UINT32, pANTLR3_COMMON_TOKEN)) createTypeToken; adaptor->createTypeTokenText = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, ANTLR3_UINT32, pANTLR3_COMMON_TOKEN, pANTLR3_UINT8)) createTypeTokenText; adaptor->createTypeText = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, ANTLR3_UINT32, pANTLR3_UINT8)) createTypeText; adaptor->dupTree = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, void *)) dupTree; } else { adaptor->nilNode = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR)) dbgNil; adaptor->addChild = (void (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, void *)) dbgAddChild; adaptor->becomeRoot = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, void *)) dbgBecomeRoot; adaptor->addChildToken = (void (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, pANTLR3_COMMON_TOKEN)) dbgAddChildToken; adaptor->becomeRootToken = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, void *)) dbgBecomeRootToken; adaptor->createTypeToken = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, ANTLR3_UINT32, pANTLR3_COMMON_TOKEN)) dbgCreateTypeToken; adaptor->createTypeTokenText = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, ANTLR3_UINT32, pANTLR3_COMMON_TOKEN, pANTLR3_UINT8)) dbgCreateTypeTokenText; adaptor->createTypeText = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, ANTLR3_UINT32, pANTLR3_UINT8)) dbgCreateTypeText; adaptor->dupTree = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, void *)) dbgDupTree; debugger->adaptor = adaptor; } adaptor->dupTreeTT = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, void *)) dupTreeTT; adaptor->rulePostProcessing = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, void *)) rulePostProcessing; adaptor->getType = (ANTLR3_UINT32 (*)(pANTLR3_BASE_TREE_ADAPTOR, void *)) getType; adaptor->setType = (void (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, ANTLR3_UINT32)) setType; adaptor->getText = (pANTLR3_STRING (*) (pANTLR3_BASE_TREE_ADAPTOR, void *)) getText; adaptor->setText8 = (void (*)(pANTLR3_BASE_TREE_ADAPTOR, pANTLR3_UINT8)) setText8; adaptor->setText = (void (*)(pANTLR3_BASE_TREE_ADAPTOR, pANTLR3_STRING)) setText; adaptor->getChild = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, ANTLR3_UINT32)) getChild; adaptor->getChildCount = (ANTLR3_UINT32 (*)(pANTLR3_BASE_TREE_ADAPTOR, void *)) getChildCount; adaptor->getUniqueID = (ANTLR3_UINT32 (*)(pANTLR3_BASE_TREE_ADAPTOR, void *)) getUniqueID; adaptor->isNilNode = (ANTLR3_BOOLEAN (*)(pANTLR3_BASE_TREE_ADAPTOR, void *)) isNilNode; adaptor->makeDot = (pANTLR3_STRING (*)(pANTLR3_BASE_TREE_ADAPTOR, void *)) makeDot; /* Remaining functions filled in by the caller. */ return; } static void defineDotNodes(pANTLR3_BASE_TREE_ADAPTOR adaptor, void * t, pANTLR3_STRING dotSpec ) { // How many nodes are we talking about? // int nCount; int i; pANTLR3_BASE_TREE child; char buff[64]; pANTLR3_STRING text; int j; // Count the nodes // nCount = adaptor->getChildCount(adaptor, 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; i<nCount; i++) { // Pick up a pointer for the child // child = adaptor->getChild(adaptor, t, i); // Name the node // sprintf(buff, "\tn%p[label=\"", child); dotSpec->append8(dotSpec, buff); text = adaptor->getText(adaptor, child); for (j = 0; j < (ANTLR3_INT32)(text->len); j++) { switch(text->charAt(text, j)) { case '"': dotSpec->append8(dotSpec, "\\\""); break; case '\n': dotSpec->append8(dotSpec, "\\n"); break; case '\r': dotSpec->append8(dotSpec, "\\r"); break; default: dotSpec->addc(dotSpec, text->charAt(text, j)); break; } } dotSpec->append8(dotSpec, "\"]\n"); // And now define the children of this child (if any) // defineDotNodes(adaptor, child, dotSpec); } // Done // return; } static void defineDotEdges(pANTLR3_BASE_TREE_ADAPTOR adaptor, void * t, pANTLR3_STRING dotSpec) { // How many nodes are we talking about? // int nCount; int i; if (t == NULL) { // No tree, so do nothing // return; } // Count the nodes // nCount = adaptor->getChildCount(adaptor, 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 (i=0; i<nCount; i++) { pANTLR3_BASE_TREE child; char buff[128]; pANTLR3_STRING text; int j; // Next child // child = adaptor->getChild(adaptor, t, i); // Create the edge relation // sprintf(buff, "\t\tn%p -> n%p\t\t// ", t, child); dotSpec->append8(dotSpec, buff); // Document the relationship // text = adaptor->getText(adaptor, t); for (j = 0; j < (ANTLR3_INT32)(text->len); j++) { switch(text->charAt(text, j)) { case '"': dotSpec->append8(dotSpec, "\\\""); break; case '\n': dotSpec->append8(dotSpec, "\\n"); break; case '\r': dotSpec->append8(dotSpec, "\\r"); break; default: dotSpec->addc(dotSpec, text->charAt(text, j)); break; } } dotSpec->append8(dotSpec, " -> "); text = adaptor->getText(adaptor, child); for (j = 0; j < (ANTLR3_INT32)(text->len); j++) { switch(text->charAt(text, j)) { case '"': dotSpec->append8(dotSpec, "\\\""); break; case '\n': dotSpec->append8(dotSpec, "\\n"); break; case '\r': dotSpec->append8(dotSpec, "\\r"); break; default: dotSpec->addc(dotSpec, text->charAt(text, j)); break; } } dotSpec->append8(dotSpec, "\n"); // Define edges for this child // defineDotEdges(adaptor, child, dotSpec); } // Done // return; } /// Produce a DOT specification for graphviz // static pANTLR3_STRING makeDot (pANTLR3_BASE_TREE_ADAPTOR adaptor, void * theTree) { // The string we are building up // pANTLR3_STRING dotSpec; char buff[64]; pANTLR3_STRING text; int j; dotSpec = adaptor->strFactory->newStr8 ( adaptor->strFactory, // Default look and feel // (pANTLR3_UINT8) "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->append8(dotSpec, "n0[label=\"EMPTY TREE\"]\n"); return dotSpec; } sprintf(buff, "\tn%p[label=\"", theTree); dotSpec->append8(dotSpec, buff); text = adaptor->getText(adaptor, theTree); for (j = 0; j < (ANTLR3_INT32)(text->len); j++) { switch(text->charAt(text, j)) { case '"': dotSpec->append8(dotSpec, "\\\""); break; case '\n': dotSpec->append8(dotSpec, "\\n"); break; case '\r': dotSpec->append8(dotSpec, "\\r"); break; default: dotSpec->addc(dotSpec, text->charAt(text, j)); break; } } dotSpec->append8(dotSpec, "\"]\n"); // First produce the node defintions // defineDotNodes(adaptor, theTree, dotSpec); dotSpec->append8(dotSpec, "\n"); defineDotEdges(adaptor, theTree, dotSpec); // Terminate the spec // dotSpec->append8(dotSpec, "\n}"); // Result // return dotSpec; } /** Create and return a nil tree node (no token payload) */ static pANTLR3_BASE_TREE nilNode (pANTLR3_BASE_TREE_ADAPTOR adaptor) { return adaptor->create(adaptor, NULL); } static pANTLR3_BASE_TREE dbgNil (pANTLR3_BASE_TREE_ADAPTOR adaptor) { pANTLR3_BASE_TREE t; t = adaptor->create (adaptor, NULL); adaptor->debugger->createNode (adaptor->debugger, t); return t; } /** Return a duplicate of the entire tree (implementation provided by the * BASE_TREE interface.) */ static pANTLR3_BASE_TREE dupTree (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t) { return adaptor->dupTreeTT(adaptor, t, NULL); } pANTLR3_BASE_TREE dupTreeTT (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, pANTLR3_BASE_TREE parent) { pANTLR3_BASE_TREE newTree; pANTLR3_BASE_TREE child; pANTLR3_BASE_TREE newSubTree; ANTLR3_UINT32 n; ANTLR3_UINT32 i; if (t == NULL) { return NULL; } newTree = t->dupNode(t); // Ensure new subtree root has parent/child index set // adaptor->setChildIndex (adaptor, newTree, t->getChildIndex(t)); adaptor->setParent (adaptor, newTree, parent); n = adaptor->getChildCount (adaptor, t); for (i=0; i < n; i++) { child = adaptor->getChild (adaptor, t, i); newSubTree = adaptor->dupTreeTT (adaptor, child, t); adaptor->addChild (adaptor, newTree, newSubTree); } return newTree; } /// Sends the required debugging events for duplicating a tree /// to the debugger. /// static void simulateTreeConstruction(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE tree) { ANTLR3_UINT32 n; ANTLR3_UINT32 i; pANTLR3_BASE_TREE child; // Send the create node event // adaptor->debugger->createNode(adaptor->debugger, tree); n = adaptor->getChildCount(adaptor, tree); for (i = 0; i < n; i++) { child = adaptor->getChild(adaptor, tree, i); simulateTreeConstruction(adaptor, child); adaptor->debugger->addChild(adaptor->debugger, tree, child); } } pANTLR3_BASE_TREE dbgDupTree (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE tree) { pANTLR3_BASE_TREE t; // Call the normal dup tree mechanism first // t = adaptor->dupTreeTT(adaptor, 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.. // simulateTreeConstruction(adaptor, t); return t; } /** Add a child to the tree t. If child is a flat tree (a list), make all * in list children of t. Warning: if t has no children, but child does * and child isNilNode then it is ok to move children to t via * t.children = child.children; i.e., without copying the array. This * is for construction and I'm not sure it's completely general for * a tree's addChild method to work this way. Make sure you differentiate * between your tree's addChild and this parser tree construction addChild * if it's not ok to move children to t with a simple assignment. */ static void addChild (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, pANTLR3_BASE_TREE child) { if (t != NULL && child != NULL) { t->addChild(t, child); } } static void dbgAddChild (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, pANTLR3_BASE_TREE child) { if (t != NULL && child != NULL) { t->addChild(t, child); adaptor->debugger->addChild(adaptor->debugger, t, child); } } /** Use the adaptor implementation to add a child node with the supplied token */ static void addChildToken (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, pANTLR3_COMMON_TOKEN child) { if (t != NULL && child != NULL) { adaptor->addChild(adaptor, t, adaptor->create(adaptor, child)); } } static void dbgAddChildToken (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, pANTLR3_COMMON_TOKEN child) { pANTLR3_BASE_TREE tc; if (t != NULL && child != NULL) { tc = adaptor->create(adaptor, child); adaptor->addChild(adaptor, t, tc); adaptor->debugger->addChild(adaptor->debugger, t, tc); } } /** If oldRoot is a nil root, just copy or move the children to newRoot. * If not a nil root, make oldRoot a child of newRoot. * * \code * old=^(nil a b c), new=r yields ^(r a b c) * old=^(a b c), new=r yields ^(r ^(a b c)) * \endcode * * If newRoot is a nil-rooted single child tree, use the single * child as the new root node. * * \code * old=^(nil a b c), new=^(nil r) yields ^(r a b c) * old=^(a b c), new=^(nil r) yields ^(r ^(a b c)) * \endcode * * If oldRoot was null, it's ok, just return newRoot (even if isNilNode). * * \code * old=null, new=r yields r * old=null, new=^(nil r) yields ^(nil r) * \endcode * * Return newRoot. Throw an exception if newRoot is not a * simple node or nil root with a single child node--it must be a root * node. If newRoot is <code>^(nil x)</endcode> return x as newRoot. * * Be advised that it's ok for newRoot to point at oldRoot's * children; i.e., you don't have to copy the list. We are * constructing these nodes so we should have this control for * efficiency. */ static pANTLR3_BASE_TREE becomeRoot (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE newRootTree, pANTLR3_BASE_TREE oldRootTree) { pANTLR3_BASE_TREE 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(newRootTree)) { if (newRootTree->getChildCount(newRootTree) > 1) { /* TODO: Handle tree exceptions */ ANTLR3_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(newRootTree, 0); // Reclaim the old nilNode() // saveRoot->reuse(saveRoot); } /* 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(newRootTree, 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(oldRootTree)) { // 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(oldRootTree); } /* Always returns new root structure */ return newRootTree; } static pANTLR3_BASE_TREE dbgBecomeRoot (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE newRootTree, pANTLR3_BASE_TREE oldRootTree) { pANTLR3_BASE_TREE t; t = becomeRoot(adaptor, newRootTree, oldRootTree); adaptor->debugger->becomeRoot(adaptor->debugger, newRootTree, oldRootTree); return t; } /** Transform ^(nil x) to x */ static pANTLR3_BASE_TREE rulePostProcessing (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE root) { pANTLR3_BASE_TREE 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(root)) { if (root->getChildCount(root) == 0) { root = NULL; } else if (root->getChildCount(root) == 1) { root = root->getChild(root, 0); root->setParent(root, NULL); root->setChildIndex(root, -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(saveRoot); } } return root; } /** Use the adaptor interface to set a new tree node with the supplied token * to the root of the tree. */ static pANTLR3_BASE_TREE becomeRootToken (pANTLR3_BASE_TREE_ADAPTOR adaptor, void * newRoot, pANTLR3_BASE_TREE oldRoot) { return adaptor->becomeRoot(adaptor, adaptor->create(adaptor, newRoot), oldRoot); } static pANTLR3_BASE_TREE dbgBecomeRootToken (pANTLR3_BASE_TREE_ADAPTOR adaptor, void * newRoot, pANTLR3_BASE_TREE oldRoot) { pANTLR3_BASE_TREE t; t = adaptor->becomeRoot(adaptor, adaptor->create(adaptor, newRoot), oldRoot); adaptor->debugger->becomeRoot(adaptor->debugger,t, oldRoot); return t; } /** Use the super class supplied create() method to create a new node * from the supplied token. */ static pANTLR3_BASE_TREE createTypeToken (pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_COMMON_TOKEN fromToken) { /* Create the new token */ fromToken = adaptor->createTokenFromToken(adaptor, fromToken); /* Set the type of the new token to that supplied */ fromToken->setType(fromToken, tokenType); /* Return a new node based upon this token */ return adaptor->create(adaptor, fromToken); } static pANTLR3_BASE_TREE dbgCreateTypeToken (pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_COMMON_TOKEN fromToken) { pANTLR3_BASE_TREE t; t = createTypeToken(adaptor, tokenType, fromToken); adaptor->debugger->createNode(adaptor->debugger, t); return t; } static pANTLR3_BASE_TREE createTypeTokenText (pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_COMMON_TOKEN fromToken, pANTLR3_UINT8 text) { /* Create the new token */ fromToken = adaptor->createTokenFromToken(adaptor, fromToken); /* Set the type of the new token to that supplied */ fromToken->setType(fromToken, tokenType); /* Set the text of the token accordingly */ fromToken->setText8(fromToken, text); /* Return a new node based upon this token */ return adaptor->create(adaptor, fromToken); } static pANTLR3_BASE_TREE dbgCreateTypeTokenText (pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_COMMON_TOKEN fromToken, pANTLR3_UINT8 text) { pANTLR3_BASE_TREE t; t = createTypeTokenText(adaptor, tokenType, fromToken, text); adaptor->debugger->createNode(adaptor->debugger, t); return t; } static pANTLR3_BASE_TREE createTypeText (pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_UINT8 text) { pANTLR3_COMMON_TOKEN fromToken; /* Create the new token */ fromToken = adaptor->createToken(adaptor, tokenType, text); /* Return a new node based upon this token */ return adaptor->create(adaptor, fromToken); } static pANTLR3_BASE_TREE dbgCreateTypeText (pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_UINT8 text) { pANTLR3_BASE_TREE t; t = createTypeText(adaptor, tokenType, text); adaptor->debugger->createNode(adaptor->debugger, t); return t; } /** Dummy implementation - will be supplied by super class */ static ANTLR3_UINT32 getType (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t) { return 0; } /** Dummy implementation - will be supplied by super class */ static void setType (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, ANTLR3_UINT32 type) { ANTLR3_FPRINTF(stderr, "Internal error - implementor of superclass containing ANTLR3_TREE_ADAPTOR did not implement setType()\n"); } /** Dummy implementation - will be supplied by super class */ static pANTLR3_STRING getText (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t) { ANTLR3_FPRINTF(stderr, "Internal error - implementor of superclass containing ANTLR3_TREE_ADAPTOR did not implement getText()\n"); return NULL; } /** Dummy implementation - will be supplied by super class */ static void setText (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_STRING t) { ANTLR3_FPRINTF(stderr, "Internal error - implementor of superclass containing ANTLR3_TREE_ADAPTOR did not implement setText()\n"); } /** Dummy implementation - will be supplied by super class */ static void setText8 (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_UINT8 t) { ANTLR3_FPRINTF(stderr, "Internal error - implementor of superclass containing ANTLR3_TREE_ADAPTOR did not implement setText()\n"); } static pANTLR3_BASE_TREE getChild (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE tree, ANTLR3_UINT32 i) { ANTLR3_FPRINTF(stderr, "Internal error - implementor of superclass containing ANTLR3_TREE_ADAPTOR did not implement getChild()\n"); return NULL; } static ANTLR3_UINT32 getChildCount (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE tree) { ANTLR3_FPRINTF(stderr, "Internal error - implementor of superclass containing ANTLR3_TREE_ADAPTOR did not implement getChildCount()\n"); return 0; } /** Returns a uniqueID for the node. Because this is the C implementation * we can just use its address suitably converted/cast to an integer. */ static ANTLR3_UINT32 getUniqueID (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE node) { return ANTLR3_UINT32_CAST(node); } static ANTLR3_BOOLEAN isNilNode (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t) { return t->isNilNode(t); }