diff options
Diffstat (limited to 'impl/antlr/libantlr3c-3.4/src/antlr3basetreeadaptor.c')
-rw-r--r-- | impl/antlr/libantlr3c-3.4/src/antlr3basetreeadaptor.c | 909 |
1 files changed, 909 insertions, 0 deletions
diff --git a/impl/antlr/libantlr3c-3.4/src/antlr3basetreeadaptor.c b/impl/antlr/libantlr3c-3.4/src/antlr3basetreeadaptor.c new file mode 100644 index 0000000..e35878f --- /dev/null +++ b/impl/antlr/libantlr3c-3.4/src/antlr3basetreeadaptor.c @@ -0,0 +1,909 @@ +/** \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); +} |