-/// \file\r
-/// Defines the implementation of the common node stream the default\r
-/// tree node stream used by ANTLR.\r
-///\r
-\r
-// [The "BSD licence"]\r
-// Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC\r
-// http://www.temporal-wave.com\r
-// http://www.linkedin.com/in/jimidle\r
-//\r
-// All rights reserved.\r
-//\r
-// Redistribution and use in source and binary forms, with or without\r
-// modification, are permitted provided that the following conditions\r
-// are met:\r
-// 1. Redistributions of source code must retain the above copyright\r
-// notice, this list of conditions and the following disclaimer.\r
-// 2. Redistributions in binary form must reproduce the above copyright\r
-// notice, this list of conditions and the following disclaimer in the\r
-// documentation and/or other materials provided with the distribution.\r
-// 3. The name of the author may not be used to endorse or promote products\r
-// derived from this software without specific prior written permission.\r
-//\r
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\r
-// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
-// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
-// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\r
-// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
-// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
-// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
-\r
-#include <antlr3commontreenodestream.h>\r
-\r
-#ifdef ANTLR3_WINDOWS\r
-#pragma warning( disable : 4100 )\r
-#endif\r
-\r
-// COMMON TREE STREAM API\r
-//\r
-static void addNavigationNode (pANTLR3_COMMON_TREE_NODE_STREAM ctns, ANTLR3_UINT32 ttype);\r
-static ANTLR3_BOOLEAN hasUniqueNavigationNodes (pANTLR3_COMMON_TREE_NODE_STREAM ctns);\r
-static pANTLR3_BASE_TREE newDownNode (pANTLR3_COMMON_TREE_NODE_STREAM ctns);\r
-static pANTLR3_BASE_TREE newUpNode (pANTLR3_COMMON_TREE_NODE_STREAM ctns);\r
-static void reset (pANTLR3_COMMON_TREE_NODE_STREAM ctns);\r
-static void push (pANTLR3_COMMON_TREE_NODE_STREAM ctns, ANTLR3_INT32 index);\r
-static ANTLR3_INT32 pop (pANTLR3_COMMON_TREE_NODE_STREAM ctns);\r
-//static ANTLR3_INT32 index (pANTLR3_COMMON_TREE_NODE_STREAM ctns);\r
-static ANTLR3_UINT32 getLookaheadSize (pANTLR3_COMMON_TREE_NODE_STREAM ctns);\r
-// TREE NODE STREAM API\r
-//\r
-static pANTLR3_BASE_TREE_ADAPTOR getTreeAdaptor (pANTLR3_TREE_NODE_STREAM tns);\r
-static pANTLR3_BASE_TREE getTreeSource (pANTLR3_TREE_NODE_STREAM tns);\r
-static pANTLR3_BASE_TREE _LT (pANTLR3_TREE_NODE_STREAM tns, ANTLR3_INT32 k);\r
-static pANTLR3_BASE_TREE get (pANTLR3_TREE_NODE_STREAM tns, ANTLR3_INT32 k);\r
-static void setUniqueNavigationNodes (pANTLR3_TREE_NODE_STREAM tns, ANTLR3_BOOLEAN uniqueNavigationNodes);\r
-static pANTLR3_STRING toString (pANTLR3_TREE_NODE_STREAM tns);\r
-static pANTLR3_STRING toStringSS (pANTLR3_TREE_NODE_STREAM tns, pANTLR3_BASE_TREE start, pANTLR3_BASE_TREE stop);\r
-static void toStringWork (pANTLR3_TREE_NODE_STREAM tns, pANTLR3_BASE_TREE start, pANTLR3_BASE_TREE stop, pANTLR3_STRING buf);\r
-static void replaceChildren (pANTLR3_TREE_NODE_STREAM tns, pANTLR3_BASE_TREE parent, ANTLR3_INT32 startChildIndex, ANTLR3_INT32 stopChildIndex, pANTLR3_BASE_TREE t);\r
-\r
-// INT STREAM API\r
-//\r
-static void consume (pANTLR3_INT_STREAM is);\r
-static ANTLR3_MARKER tindex (pANTLR3_INT_STREAM is);\r
-static ANTLR3_UINT32 _LA (pANTLR3_INT_STREAM is, ANTLR3_INT32 i);\r
-static ANTLR3_MARKER mark (pANTLR3_INT_STREAM is);\r
-static void release (pANTLR3_INT_STREAM is, ANTLR3_MARKER marker);\r
-static void rewindMark (pANTLR3_INT_STREAM is, ANTLR3_MARKER marker);\r
-static void rewindLast (pANTLR3_INT_STREAM is);\r
-static void seek (pANTLR3_INT_STREAM is, ANTLR3_MARKER index);\r
-static ANTLR3_UINT32 size (pANTLR3_INT_STREAM is);\r
-\r
-\r
-// Helper functions\r
-//\r
-static void fillBuffer (pANTLR3_COMMON_TREE_NODE_STREAM ctns, pANTLR3_BASE_TREE t);\r
-static void fillBufferRoot (pANTLR3_COMMON_TREE_NODE_STREAM ctns);\r
-\r
-// Constructors\r
-//\r
-static void antlr3TreeNodeStreamFree (pANTLR3_TREE_NODE_STREAM tns);\r
-static void antlr3CommonTreeNodeStreamFree (pANTLR3_COMMON_TREE_NODE_STREAM ctns);\r
-\r
-ANTLR3_API pANTLR3_TREE_NODE_STREAM\r
-antlr3TreeNodeStreamNew()\r
-{\r
- pANTLR3_TREE_NODE_STREAM stream;\r
-\r
- // Memory for the interface structure\r
- //\r
- stream = (pANTLR3_TREE_NODE_STREAM) ANTLR3_CALLOC(1, sizeof(ANTLR3_TREE_NODE_STREAM));\r
-\r
- if (stream == NULL)\r
- {\r
- return NULL;\r
- }\r
-\r
- // Install basic API \r
- //\r
- stream->replaceChildren = replaceChildren;\r
- stream->free = antlr3TreeNodeStreamFree;\r
- \r
- return stream;\r
-}\r
-\r
-static void\r
-antlr3TreeNodeStreamFree(pANTLR3_TREE_NODE_STREAM stream)\r
-{ \r
- ANTLR3_FREE(stream);\r
-}\r
-\r
-ANTLR3_API pANTLR3_COMMON_TREE_NODE_STREAM\r
-antlr3CommonTreeNodeStreamNewTree(pANTLR3_BASE_TREE tree, ANTLR3_UINT32 hint)\r
-{\r
- pANTLR3_COMMON_TREE_NODE_STREAM stream;\r
-\r
- stream = antlr3CommonTreeNodeStreamNew(tree->strFactory, hint);\r
-\r
- if (stream == NULL)\r
- {\r
- return NULL;\r
- }\r
- stream->root = tree;\r
-\r
- return stream;\r
-}\r
-\r
-ANTLR3_API pANTLR3_COMMON_TREE_NODE_STREAM\r
-antlr3CommonTreeNodeStreamNewStream(pANTLR3_COMMON_TREE_NODE_STREAM inStream)\r
-{\r
- pANTLR3_COMMON_TREE_NODE_STREAM stream;\r
-\r
- // Memory for the interface structure\r
- //\r
- stream = (pANTLR3_COMMON_TREE_NODE_STREAM) ANTLR3_CALLOC(1, sizeof(ANTLR3_COMMON_TREE_NODE_STREAM));\r
-\r
- if (stream == NULL)\r
- {\r
- return NULL;\r
- }\r
-\r
- // Copy in all the reusable parts of the originating stream and create new\r
- // pieces where necessary.\r
- //\r
-\r
- // String factory for tree walker\r
- //\r
- stream->stringFactory = inStream->stringFactory;\r
-\r
- // Create an adaptor for the common tree node stream\r
- //\r
- stream->adaptor = inStream->adaptor;\r
-\r
- // Create space for the tree node stream interface\r
- //\r
- stream->tnstream = antlr3TreeNodeStreamNew();\r
-\r
- if (stream->tnstream == NULL)\r
- {\r
- stream->free (stream);\r
-\r
- return NULL;\r
- }\r
-\r
- // Create space for the INT_STREAM interface\r
- //\r
- stream->tnstream->istream = antlr3IntStreamNew();\r
-\r
- if (stream->tnstream->istream == NULL)\r
- {\r
- stream->tnstream->free (stream->tnstream);\r
- stream->free (stream);\r
-\r
- return NULL;\r
- }\r
-\r
- // Install the common tree node stream API\r
- //\r
- stream->addNavigationNode = addNavigationNode;\r
- stream->hasUniqueNavigationNodes = hasUniqueNavigationNodes;\r
- stream->newDownNode = newDownNode;\r
- stream->newUpNode = newUpNode;\r
- stream->reset = reset;\r
- stream->push = push;\r
- stream->pop = pop;\r
- stream->getLookaheadSize = getLookaheadSize;\r
-\r
- stream->free = antlr3CommonTreeNodeStreamFree;\r
-\r
- // Install the tree node stream API\r
- //\r
- stream->tnstream->getTreeAdaptor = getTreeAdaptor;\r
- stream->tnstream->getTreeSource = getTreeSource;\r
- stream->tnstream->_LT = _LT;\r
- stream->tnstream->setUniqueNavigationNodes = setUniqueNavigationNodes;\r
- stream->tnstream->toString = toString;\r
- stream->tnstream->toStringSS = toStringSS;\r
- stream->tnstream->toStringWork = toStringWork;\r
- stream->tnstream->get = get;\r
-\r
- // Install INT_STREAM interface\r
- //\r
- stream->tnstream->istream->consume = consume;\r
- stream->tnstream->istream->index = tindex;\r
- stream->tnstream->istream->_LA = _LA;\r
- stream->tnstream->istream->mark = mark;\r
- stream->tnstream->istream->release = release;\r
- stream->tnstream->istream->rewind = rewindMark;\r
- stream->tnstream->istream->rewindLast = rewindLast;\r
- stream->tnstream->istream->seek = seek;\r
- stream->tnstream->istream->size = size;\r
-\r
- // Initialize data elements of INT stream\r
- //\r
- stream->tnstream->istream->type = ANTLR3_COMMONTREENODE;\r
- stream->tnstream->istream->super = (stream->tnstream);\r
-\r
- // Initialize data elements of TREE stream\r
- //\r
- stream->tnstream->ctns = stream;\r
-\r
- // Initialize data elements of the COMMON TREE NODE stream\r
- //\r
- stream->super = NULL;\r
- stream->uniqueNavigationNodes = ANTLR3_FALSE;\r
- stream->markers = NULL;\r
- stream->nodeStack = inStream->nodeStack;\r
-\r
- // Create the node list map\r
- //\r
- stream->nodes = antlr3VectorNew(DEFAULT_INITIAL_BUFFER_SIZE);\r
- stream->p = -1;\r
-\r
- // Install the navigation nodes \r
- //\r
- \r
- // Install the navigation nodes \r
- //\r
- antlr3SetCTAPI(&(stream->UP));\r
- antlr3SetCTAPI(&(stream->DOWN));\r
- antlr3SetCTAPI(&(stream->EOF_NODE));\r
- antlr3SetCTAPI(&(stream->INVALID_NODE));\r
-\r
- stream->UP.token = inStream->UP.token;\r
- inStream->UP.token->strFactory = stream->stringFactory;\r
- stream->DOWN.token = inStream->DOWN.token;\r
- inStream->DOWN.token->strFactory = stream->stringFactory;\r
- stream->EOF_NODE.token = inStream->EOF_NODE.token;\r
- inStream->EOF_NODE.token->strFactory = stream->stringFactory;\r
- stream->INVALID_NODE.token = inStream->INVALID_NODE.token;\r
- inStream->INVALID_NODE.token->strFactory= stream->stringFactory;\r
-\r
- // Reuse the root tree of the originating stream\r
- //\r
- stream->root = inStream->root;\r
-\r
- // Signal that this is a rewriting stream so we don't\r
- // free the originating tree. Anything that we rewrite or\r
- // duplicate here will be done through the adaptor or \r
- // the original tree factory.\r
- //\r
- stream->isRewriter = ANTLR3_TRUE;\r
- return stream;\r
-}\r
-\r
-ANTLR3_API pANTLR3_COMMON_TREE_NODE_STREAM\r
-antlr3CommonTreeNodeStreamNew(pANTLR3_STRING_FACTORY strFactory, ANTLR3_UINT32 hint)\r
-{\r
- pANTLR3_COMMON_TREE_NODE_STREAM stream;\r
- pANTLR3_COMMON_TOKEN token;\r
-\r
- // Memory for the interface structure\r
- //\r
- stream = (pANTLR3_COMMON_TREE_NODE_STREAM) ANTLR3_CALLOC(1, sizeof(ANTLR3_COMMON_TREE_NODE_STREAM));\r
-\r
- if (stream == NULL)\r
- {\r
- return NULL;\r
- }\r
-\r
- // String factory for tree walker\r
- //\r
- stream->stringFactory = strFactory;\r
-\r
- // Create an adaptor for the common tree node stream\r
- //\r
- stream->adaptor = ANTLR3_TREE_ADAPTORNew(strFactory);\r
-\r
- if (stream->adaptor == NULL)\r
- {\r
- stream->free(stream);\r
- return NULL;\r
- }\r
-\r
- // Create space for the tree node stream interface\r
- //\r
- stream->tnstream = antlr3TreeNodeStreamNew();\r
-\r
- if (stream->tnstream == NULL)\r
- {\r
- stream->adaptor->free (stream->adaptor);\r
- stream->free (stream);\r
-\r
- return NULL;\r
- }\r
-\r
- // Create space for the INT_STREAM interface\r
- //\r
- stream->tnstream->istream = antlr3IntStreamNew();\r
-\r
- if (stream->tnstream->istream == NULL)\r
- {\r
- stream->adaptor->free (stream->adaptor);\r
- stream->tnstream->free (stream->tnstream);\r
- stream->free (stream);\r
-\r
- return NULL;\r
- }\r
-\r
- // Install the common tree node stream API\r
- //\r
- stream->addNavigationNode = addNavigationNode;\r
- stream->hasUniqueNavigationNodes = hasUniqueNavigationNodes;\r
- stream->newDownNode = newDownNode;\r
- stream->newUpNode = newUpNode;\r
- stream->reset = reset;\r
- stream->push = push;\r
- stream->pop = pop;\r
-\r
- stream->free = antlr3CommonTreeNodeStreamFree;\r
-\r
- // Install the tree node stream API\r
- //\r
- stream->tnstream->getTreeAdaptor = getTreeAdaptor;\r
- stream->tnstream->getTreeSource = getTreeSource;\r
- stream->tnstream->_LT = _LT;\r
- stream->tnstream->setUniqueNavigationNodes = setUniqueNavigationNodes;\r
- stream->tnstream->toString = toString;\r
- stream->tnstream->toStringSS = toStringSS;\r
- stream->tnstream->toStringWork = toStringWork;\r
- stream->tnstream->get = get;\r
-\r
- // Install INT_STREAM interface\r
- //\r
- stream->tnstream->istream->consume = consume;\r
- stream->tnstream->istream->index = tindex;\r
- stream->tnstream->istream->_LA = _LA;\r
- stream->tnstream->istream->mark = mark;\r
- stream->tnstream->istream->release = release;\r
- stream->tnstream->istream->rewind = rewindMark;\r
- stream->tnstream->istream->rewindLast = rewindLast;\r
- stream->tnstream->istream->seek = seek;\r
- stream->tnstream->istream->size = size;\r
-\r
- // Initialize data elements of INT stream\r
- //\r
- stream->tnstream->istream->type = ANTLR3_COMMONTREENODE;\r
- stream->tnstream->istream->super = (stream->tnstream);\r
-\r
- // Initialize data elements of TREE stream\r
- //\r
- stream->tnstream->ctns = stream;\r
-\r
- // Initialize data elements of the COMMON TREE NODE stream\r
- //\r
- stream->super = NULL;\r
- stream->uniqueNavigationNodes = ANTLR3_FALSE;\r
- stream->markers = NULL;\r
- stream->nodeStack = antlr3StackNew(INITIAL_CALL_STACK_SIZE);\r
-\r
- // Create the node list map\r
- //\r
- if (hint == 0)\r
- {\r
- hint = DEFAULT_INITIAL_BUFFER_SIZE;\r
- }\r
- stream->nodes = antlr3VectorNew(hint);\r
- stream->p = -1;\r
-\r
- // Install the navigation nodes \r
- //\r
- antlr3SetCTAPI(&(stream->UP));\r
- antlr3SetCTAPI(&(stream->DOWN));\r
- antlr3SetCTAPI(&(stream->EOF_NODE));\r
- antlr3SetCTAPI(&(stream->INVALID_NODE));\r
-\r
- token = antlr3CommonTokenNew(ANTLR3_TOKEN_UP);\r
- token->strFactory = strFactory;\r
- token->textState = ANTLR3_TEXT_CHARP;\r
- token->tokText.chars = (pANTLR3_UCHAR)"UP";\r
- stream->UP.token = token;\r
-\r
- token = antlr3CommonTokenNew(ANTLR3_TOKEN_DOWN);\r
- token->strFactory = strFactory;\r
- token->textState = ANTLR3_TEXT_CHARP;\r
- token->tokText.chars = (pANTLR3_UCHAR)"DOWN";\r
- stream->DOWN.token = token;\r
-\r
- token = antlr3CommonTokenNew(ANTLR3_TOKEN_EOF);\r
- token->strFactory = strFactory;\r
- token->textState = ANTLR3_TEXT_CHARP;\r
- token->tokText.chars = (pANTLR3_UCHAR)"EOF";\r
- stream->EOF_NODE.token = token;\r
-\r
- token = antlr3CommonTokenNew(ANTLR3_TOKEN_INVALID);\r
- token->strFactory = strFactory;\r
- token->textState = ANTLR3_TEXT_CHARP;\r
- token->tokText.chars = (pANTLR3_UCHAR)"INVALID";\r
- stream->INVALID_NODE.token = token;\r
-\r
-\r
- return stream;\r
-}\r
-\r
-/// Free up any resources that belong to this common tree node stream.\r
-///\r
-static void antlr3CommonTreeNodeStreamFree (pANTLR3_COMMON_TREE_NODE_STREAM ctns)\r
-{\r
-\r
- // If this is a rewrting stream, then certain resources\r
- // belong to the originating node stream and we do not\r
- // free them here.\r
- //\r
- if (ctns->isRewriter != ANTLR3_TRUE)\r
- {\r
- ctns->adaptor ->free (ctns->adaptor);\r
-\r
- if (ctns->nodeStack != NULL)\r
- {\r
- ctns->nodeStack->free(ctns->nodeStack);\r
- }\r
-\r
- ANTLR3_FREE(ctns->INVALID_NODE.token);\r
- ANTLR3_FREE(ctns->EOF_NODE.token);\r
- ANTLR3_FREE(ctns->DOWN.token);\r
- ANTLR3_FREE(ctns->UP.token);\r
- }\r
- \r
- if (ctns->nodes != NULL)\r
- {\r
- ctns->nodes ->free (ctns->nodes);\r
- }\r
- ctns->tnstream->istream ->free (ctns->tnstream->istream);\r
- ctns->tnstream ->free (ctns->tnstream);\r
-\r
-\r
- ANTLR3_FREE(ctns);\r
-}\r
-\r
-// ------------------------------------------------------------------------------\r
-// Local helpers\r
-//\r
-\r
-/// Walk and fill the tree node buffer from the root tree\r
-///\r
-static void\r
-fillBufferRoot(pANTLR3_COMMON_TREE_NODE_STREAM ctns)\r
-{\r
- // Call the generic buffer routine with the root as the\r
- // argument\r
- //\r
- fillBuffer(ctns, ctns->root);\r
- ctns->p = 0; // Indicate we are at buffer start\r
-}\r
-\r
-/// Walk tree with depth-first-search and fill nodes buffer.\r
-/// Don't add in DOWN, UP nodes if the supplied tree is a list (t is isNilNode)\r
-// such as the root tree is.\r
-///\r
-static void\r
-fillBuffer(pANTLR3_COMMON_TREE_NODE_STREAM ctns, pANTLR3_BASE_TREE t)\r
-{\r
- ANTLR3_BOOLEAN nilNode;\r
- ANTLR3_UINT32 nCount;\r
- ANTLR3_UINT32 c;\r
-\r
- nilNode = ctns->adaptor->isNilNode(ctns->adaptor, t);\r
-\r
- // If the supplied node is not a nil (list) node then we\r
- // add in the node itself to the vector\r
- //\r
- if (nilNode == ANTLR3_FALSE)\r
- {\r
- ctns->nodes->add(ctns->nodes, t, NULL); \r
- }\r
-\r
- // Only add a DOWN node if the tree is not a nil tree and\r
- // the tree does have children.\r
- //\r
- nCount = t->getChildCount(t);\r
-\r
- if (nilNode == ANTLR3_FALSE && nCount>0)\r
- {\r
- ctns->addNavigationNode(ctns, ANTLR3_TOKEN_DOWN);\r
- }\r
-\r
- // We always add any children the tree contains, which is\r
- // a recursive call to this function, which will cause similar\r
- // recursion and implement a depth first addition\r
- //\r
- for (c = 0; c < nCount; c++)\r
- {\r
- fillBuffer(ctns, ctns->adaptor->getChild(ctns->adaptor, t, c));\r
- }\r
-\r
- // If the tree had children and was not a nil (list) node, then we\r
- // we need to add an UP node here to match the DOWN node\r
- //\r
- if (nilNode == ANTLR3_FALSE && nCount > 0)\r
- {\r
- ctns->addNavigationNode(ctns, ANTLR3_TOKEN_UP);\r
- }\r
-}\r
-\r
-\r
-// ------------------------------------------------------------------------------\r
-// Interface functions\r
-//\r
-\r
-/// Reset the input stream to the start of the input nodes.\r
-///\r
-static void \r
-reset (pANTLR3_COMMON_TREE_NODE_STREAM ctns)\r
-{\r
- if (ctns->p != -1)\r
- {\r
- ctns->p = 0;\r
- }\r
- ctns->tnstream->istream->lastMarker = 0;\r
-\r
-\r
- // Free and reset the node stack only if this is not\r
- // a rewriter, which is going to reuse the originating\r
- // node streams node stack\r
- //\r
- if (ctns->isRewriter != ANTLR3_TRUE)\r
- {\r
- if (ctns->nodeStack != NULL)\r
- {\r
- ctns->nodeStack->free(ctns->nodeStack);\r
- ctns->nodeStack = antlr3StackNew(INITIAL_CALL_STACK_SIZE);\r
- }\r
- }\r
-}\r
-\r
-\r
-static pANTLR3_BASE_TREE\r
-LB(pANTLR3_TREE_NODE_STREAM tns, ANTLR3_INT32 k)\r
-{\r
- if ( k==0)\r
- {\r
- return &(tns->ctns->INVALID_NODE.baseTree);\r
- }\r
-\r
- if ( (tns->ctns->p - k) < 0)\r
- {\r
- return &(tns->ctns->INVALID_NODE.baseTree);\r
- }\r
-\r
- return tns->ctns->nodes->get(tns->ctns->nodes, tns->ctns->p - k);\r
-}\r
-\r
-/// Get tree node at current input pointer + i ahead where i=1 is next node.\r
-/// i<0 indicates nodes in the past. So -1 is previous node and -2 is\r
-/// two nodes ago. LT(0) is undefined. For i>=n, return null.\r
-/// Return null for LT(0) and any index that results in an absolute address\r
-/// that is negative.\r
-///\r
-/// This is analogous to the _LT() method of the TokenStream, but this\r
-/// returns a tree node instead of a token. Makes code gen identical\r
-/// for both parser and tree grammars. :)\r
-///\r
-static pANTLR3_BASE_TREE \r
-_LT (pANTLR3_TREE_NODE_STREAM tns, ANTLR3_INT32 k)\r
-{\r
- if (tns->ctns->p == -1)\r
- {\r
- fillBufferRoot(tns->ctns);\r
- }\r
-\r
- if (k < 0)\r
- {\r
- return LB(tns, -k);\r
- }\r
- else if (k == 0)\r
- {\r
- return &(tns->ctns->INVALID_NODE.baseTree);\r
- }\r
-\r
- // k was a legitimate request, \r
- //\r
- if (( tns->ctns->p + k - 1) >= (ANTLR3_INT32)(tns->ctns->nodes->count))\r
- {\r
- return &(tns->ctns->EOF_NODE.baseTree);\r
- }\r
-\r
- return tns->ctns->nodes->get(tns->ctns->nodes, tns->ctns->p + k - 1);\r
-}\r
-\r
-/// Where is this stream pulling nodes from? This is not the name, but\r
-/// the object that provides node objects.\r
-///\r
-static pANTLR3_BASE_TREE \r
-getTreeSource (pANTLR3_TREE_NODE_STREAM tns)\r
-{\r
- return tns->ctns->root;\r
-}\r
-\r
-/// Consume the next node from the input stream\r
-///\r
-static void \r
-consume (pANTLR3_INT_STREAM is)\r
-{\r
- pANTLR3_TREE_NODE_STREAM tns;\r
- pANTLR3_COMMON_TREE_NODE_STREAM ctns;\r
-\r
- tns = (pANTLR3_TREE_NODE_STREAM)(is->super);\r
- ctns = tns->ctns;\r
-\r
- if (ctns->p == -1)\r
- {\r
- fillBufferRoot(ctns);\r
- }\r
- ctns->p++;\r
-}\r
-\r
-static ANTLR3_UINT32 \r
-_LA (pANTLR3_INT_STREAM is, ANTLR3_INT32 i)\r
-{\r
- pANTLR3_TREE_NODE_STREAM tns;\r
- pANTLR3_BASE_TREE t;\r
-\r
- tns = (pANTLR3_TREE_NODE_STREAM)(is->super);\r
-\r
- // Ask LT for the 'token' at that position\r
- //\r
- t = tns->_LT(tns, i);\r
-\r
- if (t == NULL)\r
- {\r
- return ANTLR3_TOKEN_INVALID;\r
- }\r
-\r
- // Token node was there so return the type of it\r
- //\r
- return t->getType(t);\r
-}\r
-\r
-/// Mark the state of the input stream so that we can come back to it\r
-/// after a syntactic predicate and so on.\r
-///\r
-static ANTLR3_MARKER \r
-mark (pANTLR3_INT_STREAM is)\r
-{\r
- pANTLR3_TREE_NODE_STREAM tns;\r
- pANTLR3_COMMON_TREE_NODE_STREAM ctns;\r
-\r
- tns = (pANTLR3_TREE_NODE_STREAM)(is->super);\r
- ctns = tns->ctns;\r
-\r
- if (tns->ctns->p == -1)\r
- {\r
- fillBufferRoot(tns->ctns);\r
- }\r
-\r
- // Return the current mark point\r
- //\r
- ctns->tnstream->istream->lastMarker = ctns->tnstream->istream->index(ctns->tnstream->istream);\r
-\r
- return ctns->tnstream->istream->lastMarker;\r
-}\r
-\r
-static void \r
-release (pANTLR3_INT_STREAM is, ANTLR3_MARKER marker)\r
-{\r
-}\r
-\r
-/// Rewind the current state of the tree walk to the state it\r
-/// was in when mark() was called and it returned marker. Also,\r
-/// wipe out the lookahead which will force reloading a few nodes\r
-/// but it is better than making a copy of the lookahead buffer\r
-/// upon mark().\r
-///\r
-static void \r
-rewindMark (pANTLR3_INT_STREAM is, ANTLR3_MARKER marker)\r
-{\r
- is->seek(is, marker);\r
-}\r
-\r
-static void \r
-rewindLast (pANTLR3_INT_STREAM is)\r
-{\r
- is->seek(is, is->lastMarker);\r
-}\r
-\r
-/// consume() ahead until we hit index. Can't just jump ahead--must\r
-/// spit out the navigation nodes.\r
-///\r
-static void \r
-seek (pANTLR3_INT_STREAM is, ANTLR3_MARKER index)\r
-{\r
- pANTLR3_TREE_NODE_STREAM tns;\r
- pANTLR3_COMMON_TREE_NODE_STREAM ctns;\r
-\r
- tns = (pANTLR3_TREE_NODE_STREAM)(is->super);\r
- ctns = tns->ctns;\r
-\r
- ctns->p = ANTLR3_UINT32_CAST(index);\r
-}\r
-\r
-static ANTLR3_MARKER \r
-tindex (pANTLR3_INT_STREAM is)\r
-{\r
- pANTLR3_TREE_NODE_STREAM tns;\r
- pANTLR3_COMMON_TREE_NODE_STREAM ctns;\r
-\r
- tns = (pANTLR3_TREE_NODE_STREAM)(is->super);\r
- ctns = tns->ctns;\r
-\r
- return (ANTLR3_MARKER)(ctns->p);\r
-}\r
-\r
-/// Expensive to compute the size of the whole tree while parsing.\r
-/// This method only returns how much input has been seen so far. So\r
-/// after parsing it returns true size.\r
-///\r
-static ANTLR3_UINT32 \r
-size (pANTLR3_INT_STREAM is)\r
-{\r
- pANTLR3_TREE_NODE_STREAM tns;\r
- pANTLR3_COMMON_TREE_NODE_STREAM ctns;\r
-\r
- tns = (pANTLR3_TREE_NODE_STREAM)(is->super);\r
- ctns = tns->ctns;\r
-\r
- if (ctns->p == -1)\r
- {\r
- fillBufferRoot(ctns);\r
- }\r
-\r
- return ctns->nodes->size(ctns->nodes);\r
-}\r
-\r
-/// As we flatten the tree, we use UP, DOWN nodes to represent\r
-/// the tree structure. When debugging we need unique nodes\r
-/// so instantiate new ones when uniqueNavigationNodes is true.\r
-///\r
-static void \r
-addNavigationNode (pANTLR3_COMMON_TREE_NODE_STREAM ctns, ANTLR3_UINT32 ttype)\r
-{\r
- pANTLR3_BASE_TREE node;\r
-\r
- node = NULL;\r
-\r
- if (ttype == ANTLR3_TOKEN_DOWN)\r
- {\r
- if (ctns->hasUniqueNavigationNodes(ctns) == ANTLR3_TRUE)\r
- {\r
- node = ctns->newDownNode(ctns);\r
- }\r
- else\r
- {\r
- node = &(ctns->DOWN.baseTree);\r
- }\r
- }\r
- else\r
- {\r
- if (ctns->hasUniqueNavigationNodes(ctns) == ANTLR3_TRUE)\r
- {\r
- node = ctns->newUpNode(ctns);\r
- }\r
- else\r
- {\r
- node = &(ctns->UP.baseTree);\r
- }\r
- }\r
-\r
- // Now add the node we decided upon.\r
- //\r
- ctns->nodes->add(ctns->nodes, node, NULL);\r
-}\r
-\r
-\r
-static pANTLR3_BASE_TREE_ADAPTOR \r
-getTreeAdaptor (pANTLR3_TREE_NODE_STREAM tns)\r
-{\r
- return tns->ctns->adaptor;\r
-}\r
-\r
-static ANTLR3_BOOLEAN \r
-hasUniqueNavigationNodes (pANTLR3_COMMON_TREE_NODE_STREAM ctns)\r
-{\r
- return ctns->uniqueNavigationNodes;\r
-}\r
-\r
-static void \r
-setUniqueNavigationNodes (pANTLR3_TREE_NODE_STREAM tns, ANTLR3_BOOLEAN uniqueNavigationNodes)\r
-{\r
- tns->ctns->uniqueNavigationNodes = uniqueNavigationNodes;\r
-}\r
-\r
-\r
-/// Print out the entire tree including DOWN/UP nodes. Uses\r
-/// a recursive walk. Mostly useful for testing as it yields\r
-/// the token types not text.\r
-///\r
-static pANTLR3_STRING \r
-toString (pANTLR3_TREE_NODE_STREAM tns)\r
-{\r
-\r
- return tns->toStringSS(tns, tns->ctns->root, NULL);\r
-}\r
-\r
-static pANTLR3_STRING \r
-toStringSS (pANTLR3_TREE_NODE_STREAM tns, pANTLR3_BASE_TREE start, pANTLR3_BASE_TREE stop)\r
-{\r
- pANTLR3_STRING buf;\r
-\r
- buf = tns->ctns->stringFactory->newRaw(tns->ctns->stringFactory);\r
-\r
- tns->toStringWork(tns, start, stop, buf);\r
-\r
- return buf;\r
-}\r
-\r
-static void \r
-toStringWork (pANTLR3_TREE_NODE_STREAM tns, pANTLR3_BASE_TREE p, pANTLR3_BASE_TREE stop, pANTLR3_STRING buf)\r
-{\r
-\r
- ANTLR3_UINT32 n;\r
- ANTLR3_UINT32 c;\r
-\r
- if (!p->isNilNode(p) )\r
- {\r
- pANTLR3_STRING text;\r
-\r
- text = p->toString(p);\r
-\r
- if (text == NULL)\r
- {\r
- text = tns->ctns->stringFactory->newRaw(tns->ctns->stringFactory);\r
-\r
- text->addc (text, ' ');\r
- text->addi (text, p->getType(p));\r
- }\r
-\r
- buf->appendS(buf, text);\r
- }\r
-\r
- if (p == stop)\r
- {\r
- return; /* Finished */\r
- }\r
-\r
- n = p->getChildCount(p);\r
-\r
- if (n > 0 && ! p->isNilNode(p) )\r
- {\r
- buf->addc (buf, ' ');\r
- buf->addi (buf, ANTLR3_TOKEN_DOWN);\r
- }\r
-\r
- for (c = 0; c<n ; c++)\r
- {\r
- pANTLR3_BASE_TREE child;\r
-\r
- child = p->getChild(p, c);\r
- tns->toStringWork(tns, child, stop, buf);\r
- }\r
-\r
- if (n > 0 && ! p->isNilNode(p) )\r
- {\r
- buf->addc (buf, ' ');\r
- buf->addi (buf, ANTLR3_TOKEN_UP);\r
- }\r
-}\r
-\r
-static ANTLR3_UINT32 \r
-getLookaheadSize (pANTLR3_COMMON_TREE_NODE_STREAM ctns)\r
-{\r
- return ctns->tail < ctns->head \r
- ? (ctns->lookAheadLength - ctns->head + ctns->tail)\r
- : (ctns->tail - ctns->head);\r
-}\r
-\r
-static pANTLR3_BASE_TREE \r
-newDownNode (pANTLR3_COMMON_TREE_NODE_STREAM ctns)\r
-{\r
- pANTLR3_COMMON_TREE dNode;\r
- pANTLR3_COMMON_TOKEN token;\r
-\r
- token = antlr3CommonTokenNew(ANTLR3_TOKEN_DOWN);\r
- token->textState = ANTLR3_TEXT_CHARP;\r
- token->tokText.chars = (pANTLR3_UCHAR)"DOWN";\r
- dNode = antlr3CommonTreeNewFromToken(token);\r
-\r
- return &(dNode->baseTree);\r
-}\r
-\r
-static pANTLR3_BASE_TREE \r
-newUpNode (pANTLR3_COMMON_TREE_NODE_STREAM ctns)\r
-{\r
- pANTLR3_COMMON_TREE uNode;\r
- pANTLR3_COMMON_TOKEN token;\r
-\r
- token = antlr3CommonTokenNew(ANTLR3_TOKEN_UP);\r
- token->textState = ANTLR3_TEXT_CHARP;\r
- token->tokText.chars = (pANTLR3_UCHAR)"UP";\r
- uNode = antlr3CommonTreeNewFromToken(token);\r
-\r
- return &(uNode->baseTree);\r
-}\r
-\r
-/// Replace from start to stop child index of parent with t, which might\r
-/// be a list. Number of children may be different\r
-/// after this call. The stream is notified because it is walking the\r
-/// tree and might need to know you are monkey-ing with the underlying\r
-/// tree. Also, it might be able to modify the node stream to avoid\r
-/// re-streaming for future phases.\r
-///\r
-/// If parent is null, don't do anything; must be at root of overall tree.\r
-/// Can't replace whatever points to the parent externally. Do nothing.\r
-///\r
-static void \r
-replaceChildren (pANTLR3_TREE_NODE_STREAM tns, pANTLR3_BASE_TREE parent, ANTLR3_INT32 startChildIndex, ANTLR3_INT32 stopChildIndex, pANTLR3_BASE_TREE t)\r
-{\r
- if (parent != NULL)\r
- {\r
- pANTLR3_BASE_TREE_ADAPTOR adaptor;\r
- pANTLR3_COMMON_TREE_ADAPTOR cta;\r
-\r
- adaptor = tns->getTreeAdaptor(tns);\r
- cta = (pANTLR3_COMMON_TREE_ADAPTOR)(adaptor->super);\r
-\r
- adaptor->replaceChildren(adaptor, parent, startChildIndex, stopChildIndex, t);\r
- }\r
-}\r
-\r
-static pANTLR3_BASE_TREE\r
-get (pANTLR3_TREE_NODE_STREAM tns, ANTLR3_INT32 k)\r
-{\r
- if (tns->ctns->p == -1)\r
- {\r
- fillBufferRoot(tns->ctns);\r
- }\r
-\r
- return tns->ctns->nodes->get(tns->ctns->nodes, k);\r
-}\r
-\r
-static void\r
-push (pANTLR3_COMMON_TREE_NODE_STREAM ctns, ANTLR3_INT32 index)\r
-{\r
- ctns->nodeStack->push(ctns->nodeStack, ANTLR3_FUNC_PTR(ctns->p), NULL); // Save current index\r
- ctns->tnstream->istream->seek(ctns->tnstream->istream, index);\r
-}\r
-\r
-static ANTLR3_INT32\r
-pop (pANTLR3_COMMON_TREE_NODE_STREAM ctns)\r
-{\r
- ANTLR3_INT32 retVal;\r
-\r
- retVal = ANTLR3_UINT32_CAST(ctns->nodeStack->pop(ctns->nodeStack));\r
- ctns->tnstream->istream->seek(ctns->tnstream->istream, retVal);\r
- return retVal;\r
-}\r
+/// \file
+/// Defines the implementation of the common node stream the default
+/// tree node stream used by ANTLR.
+///
+
+// [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 <antlr3commontreenodestream.h>
+
+#ifdef ANTLR3_WINDOWS
+#pragma warning( disable : 4100 )
+#endif
+
+// COMMON TREE STREAM API
+//
+static void addNavigationNode (pANTLR3_COMMON_TREE_NODE_STREAM ctns, ANTLR3_UINT32 ttype);
+static ANTLR3_BOOLEAN hasUniqueNavigationNodes (pANTLR3_COMMON_TREE_NODE_STREAM ctns);
+static pANTLR3_BASE_TREE newDownNode (pANTLR3_COMMON_TREE_NODE_STREAM ctns);
+static pANTLR3_BASE_TREE newUpNode (pANTLR3_COMMON_TREE_NODE_STREAM ctns);
+static void reset (pANTLR3_COMMON_TREE_NODE_STREAM ctns);
+static void push (pANTLR3_COMMON_TREE_NODE_STREAM ctns, ANTLR3_INT32 index);
+static ANTLR3_INT32 pop (pANTLR3_COMMON_TREE_NODE_STREAM ctns);
+//static ANTLR3_INT32 index (pANTLR3_COMMON_TREE_NODE_STREAM ctns);
+static ANTLR3_UINT32 getLookaheadSize (pANTLR3_COMMON_TREE_NODE_STREAM ctns);
+// TREE NODE STREAM API
+//
+static pANTLR3_BASE_TREE_ADAPTOR getTreeAdaptor (pANTLR3_TREE_NODE_STREAM tns);
+static pANTLR3_BASE_TREE getTreeSource (pANTLR3_TREE_NODE_STREAM tns);
+static pANTLR3_BASE_TREE _LT (pANTLR3_TREE_NODE_STREAM tns, ANTLR3_INT32 k);
+static pANTLR3_BASE_TREE get (pANTLR3_TREE_NODE_STREAM tns, ANTLR3_INT32 k);
+static void setUniqueNavigationNodes (pANTLR3_TREE_NODE_STREAM tns, ANTLR3_BOOLEAN uniqueNavigationNodes);
+static pANTLR3_STRING toString (pANTLR3_TREE_NODE_STREAM tns);
+static pANTLR3_STRING toStringSS (pANTLR3_TREE_NODE_STREAM tns, pANTLR3_BASE_TREE start, pANTLR3_BASE_TREE stop);
+static void toStringWork (pANTLR3_TREE_NODE_STREAM tns, pANTLR3_BASE_TREE start, pANTLR3_BASE_TREE stop, pANTLR3_STRING buf);
+static void replaceChildren (pANTLR3_TREE_NODE_STREAM tns, pANTLR3_BASE_TREE parent, ANTLR3_INT32 startChildIndex, ANTLR3_INT32 stopChildIndex, pANTLR3_BASE_TREE t);
+
+// INT STREAM API
+//
+static void consume (pANTLR3_INT_STREAM is);
+static ANTLR3_MARKER tindex (pANTLR3_INT_STREAM is);
+static ANTLR3_UINT32 _LA (pANTLR3_INT_STREAM is, ANTLR3_INT32 i);
+static ANTLR3_MARKER mark (pANTLR3_INT_STREAM is);
+static void release (pANTLR3_INT_STREAM is, ANTLR3_MARKER marker);
+static void rewindMark (pANTLR3_INT_STREAM is, ANTLR3_MARKER marker);
+static void rewindLast (pANTLR3_INT_STREAM is);
+static void seek (pANTLR3_INT_STREAM is, ANTLR3_MARKER index);
+static ANTLR3_UINT32 size (pANTLR3_INT_STREAM is);
+
+
+// Helper functions
+//
+static void fillBuffer (pANTLR3_COMMON_TREE_NODE_STREAM ctns, pANTLR3_BASE_TREE t);
+static void fillBufferRoot (pANTLR3_COMMON_TREE_NODE_STREAM ctns);
+
+// Constructors
+//
+static void antlr3TreeNodeStreamFree (pANTLR3_TREE_NODE_STREAM tns);
+static void antlr3CommonTreeNodeStreamFree (pANTLR3_COMMON_TREE_NODE_STREAM ctns);
+
+ANTLR3_API pANTLR3_TREE_NODE_STREAM
+antlr3TreeNodeStreamNew()
+{
+ pANTLR3_TREE_NODE_STREAM stream;
+
+ // Memory for the interface structure
+ //
+ stream = (pANTLR3_TREE_NODE_STREAM) ANTLR3_CALLOC(1, sizeof(ANTLR3_TREE_NODE_STREAM));
+
+ if (stream == NULL)
+ {
+ return NULL;
+ }
+
+ // Install basic API
+ //
+ stream->replaceChildren = replaceChildren;
+ stream->free = antlr3TreeNodeStreamFree;
+
+ return stream;
+}
+
+static void
+antlr3TreeNodeStreamFree(pANTLR3_TREE_NODE_STREAM stream)
+{
+ ANTLR3_FREE(stream);
+}
+
+ANTLR3_API pANTLR3_COMMON_TREE_NODE_STREAM
+antlr3CommonTreeNodeStreamNewTree(pANTLR3_BASE_TREE tree, ANTLR3_UINT32 hint)
+{
+ pANTLR3_COMMON_TREE_NODE_STREAM stream;
+
+ stream = antlr3CommonTreeNodeStreamNew(tree->strFactory, hint);
+
+ if (stream == NULL)
+ {
+ return NULL;
+ }
+ stream->root = tree;
+
+ return stream;
+}
+
+ANTLR3_API pANTLR3_COMMON_TREE_NODE_STREAM
+antlr3CommonTreeNodeStreamNewStream(pANTLR3_COMMON_TREE_NODE_STREAM inStream)
+{
+ pANTLR3_COMMON_TREE_NODE_STREAM stream;
+
+ // Memory for the interface structure
+ //
+ stream = (pANTLR3_COMMON_TREE_NODE_STREAM) ANTLR3_CALLOC(1, sizeof(ANTLR3_COMMON_TREE_NODE_STREAM));
+
+ if (stream == NULL)
+ {
+ return NULL;
+ }
+
+ // Copy in all the reusable parts of the originating stream and create new
+ // pieces where necessary.
+ //
+
+ // String factory for tree walker
+ //
+ stream->stringFactory = inStream->stringFactory;
+
+ // Create an adaptor for the common tree node stream
+ //
+ stream->adaptor = inStream->adaptor;
+
+ // Create space for the tree node stream interface
+ //
+ stream->tnstream = antlr3TreeNodeStreamNew();
+
+ if (stream->tnstream == NULL)
+ {
+ stream->free (stream);
+
+ return NULL;
+ }
+
+ // Create space for the INT_STREAM interface
+ //
+ stream->tnstream->istream = antlr3IntStreamNew();
+
+ if (stream->tnstream->istream == NULL)
+ {
+ stream->tnstream->free (stream->tnstream);
+ stream->free (stream);
+
+ return NULL;
+ }
+
+ // Install the common tree node stream API
+ //
+ stream->addNavigationNode = addNavigationNode;
+ stream->hasUniqueNavigationNodes = hasUniqueNavigationNodes;
+ stream->newDownNode = newDownNode;
+ stream->newUpNode = newUpNode;
+ stream->reset = reset;
+ stream->push = push;
+ stream->pop = pop;
+ stream->getLookaheadSize = getLookaheadSize;
+
+ stream->free = antlr3CommonTreeNodeStreamFree;
+
+ // Install the tree node stream API
+ //
+ stream->tnstream->getTreeAdaptor = getTreeAdaptor;
+ stream->tnstream->getTreeSource = getTreeSource;
+ stream->tnstream->_LT = _LT;
+ stream->tnstream->setUniqueNavigationNodes = setUniqueNavigationNodes;
+ stream->tnstream->toString = toString;
+ stream->tnstream->toStringSS = toStringSS;
+ stream->tnstream->toStringWork = toStringWork;
+ stream->tnstream->get = get;
+
+ // Install INT_STREAM interface
+ //
+ stream->tnstream->istream->consume = consume;
+ stream->tnstream->istream->index = tindex;
+ stream->tnstream->istream->_LA = _LA;
+ stream->tnstream->istream->mark = mark;
+ stream->tnstream->istream->release = release;
+ stream->tnstream->istream->rewind = rewindMark;
+ stream->tnstream->istream->rewindLast = rewindLast;
+ stream->tnstream->istream->seek = seek;
+ stream->tnstream->istream->size = size;
+
+ // Initialize data elements of INT stream
+ //
+ stream->tnstream->istream->type = ANTLR3_COMMONTREENODE;
+ stream->tnstream->istream->super = (stream->tnstream);
+
+ // Initialize data elements of TREE stream
+ //
+ stream->tnstream->ctns = stream;
+
+ // Initialize data elements of the COMMON TREE NODE stream
+ //
+ stream->super = NULL;
+ stream->uniqueNavigationNodes = ANTLR3_FALSE;
+ stream->markers = NULL;
+ stream->nodeStack = inStream->nodeStack;
+
+ // Create the node list map
+ //
+ stream->nodes = antlr3VectorNew(DEFAULT_INITIAL_BUFFER_SIZE);
+ stream->p = -1;
+
+ // Install the navigation nodes
+ //
+
+ // Install the navigation nodes
+ //
+ antlr3SetCTAPI(&(stream->UP));
+ antlr3SetCTAPI(&(stream->DOWN));
+ antlr3SetCTAPI(&(stream->EOF_NODE));
+ antlr3SetCTAPI(&(stream->INVALID_NODE));
+
+ stream->UP.token = inStream->UP.token;
+ inStream->UP.token->strFactory = stream->stringFactory;
+ stream->DOWN.token = inStream->DOWN.token;
+ inStream->DOWN.token->strFactory = stream->stringFactory;
+ stream->EOF_NODE.token = inStream->EOF_NODE.token;
+ inStream->EOF_NODE.token->strFactory = stream->stringFactory;
+ stream->INVALID_NODE.token = inStream->INVALID_NODE.token;
+ inStream->INVALID_NODE.token->strFactory= stream->stringFactory;
+
+ // Reuse the root tree of the originating stream
+ //
+ stream->root = inStream->root;
+
+ // Signal that this is a rewriting stream so we don't
+ // free the originating tree. Anything that we rewrite or
+ // duplicate here will be done through the adaptor or
+ // the original tree factory.
+ //
+ stream->isRewriter = ANTLR3_TRUE;
+ return stream;
+}
+
+ANTLR3_API pANTLR3_COMMON_TREE_NODE_STREAM
+antlr3CommonTreeNodeStreamNew(pANTLR3_STRING_FACTORY strFactory, ANTLR3_UINT32 hint)
+{
+ pANTLR3_COMMON_TREE_NODE_STREAM stream;
+ pANTLR3_COMMON_TOKEN token;
+
+ // Memory for the interface structure
+ //
+ stream = (pANTLR3_COMMON_TREE_NODE_STREAM) ANTLR3_CALLOC(1, sizeof(ANTLR3_COMMON_TREE_NODE_STREAM));
+
+ if (stream == NULL)
+ {
+ return NULL;
+ }
+
+ // String factory for tree walker
+ //
+ stream->stringFactory = strFactory;
+
+ // Create an adaptor for the common tree node stream
+ //
+ stream->adaptor = ANTLR3_TREE_ADAPTORNew(strFactory);
+
+ if (stream->adaptor == NULL)
+ {
+ stream->free(stream);
+ return NULL;
+ }
+
+ // Create space for the tree node stream interface
+ //
+ stream->tnstream = antlr3TreeNodeStreamNew();
+
+ if (stream->tnstream == NULL)
+ {
+ stream->adaptor->free (stream->adaptor);
+ stream->free (stream);
+
+ return NULL;
+ }
+
+ // Create space for the INT_STREAM interface
+ //
+ stream->tnstream->istream = antlr3IntStreamNew();
+
+ if (stream->tnstream->istream == NULL)
+ {
+ stream->adaptor->free (stream->adaptor);
+ stream->tnstream->free (stream->tnstream);
+ stream->free (stream);
+
+ return NULL;
+ }
+
+ // Install the common tree node stream API
+ //
+ stream->addNavigationNode = addNavigationNode;
+ stream->hasUniqueNavigationNodes = hasUniqueNavigationNodes;
+ stream->newDownNode = newDownNode;
+ stream->newUpNode = newUpNode;
+ stream->reset = reset;
+ stream->push = push;
+ stream->pop = pop;
+
+ stream->free = antlr3CommonTreeNodeStreamFree;
+
+ // Install the tree node stream API
+ //
+ stream->tnstream->getTreeAdaptor = getTreeAdaptor;
+ stream->tnstream->getTreeSource = getTreeSource;
+ stream->tnstream->_LT = _LT;
+ stream->tnstream->setUniqueNavigationNodes = setUniqueNavigationNodes;
+ stream->tnstream->toString = toString;
+ stream->tnstream->toStringSS = toStringSS;
+ stream->tnstream->toStringWork = toStringWork;
+ stream->tnstream->get = get;
+
+ // Install INT_STREAM interface
+ //
+ stream->tnstream->istream->consume = consume;
+ stream->tnstream->istream->index = tindex;
+ stream->tnstream->istream->_LA = _LA;
+ stream->tnstream->istream->mark = mark;
+ stream->tnstream->istream->release = release;
+ stream->tnstream->istream->rewind = rewindMark;
+ stream->tnstream->istream->rewindLast = rewindLast;
+ stream->tnstream->istream->seek = seek;
+ stream->tnstream->istream->size = size;
+
+ // Initialize data elements of INT stream
+ //
+ stream->tnstream->istream->type = ANTLR3_COMMONTREENODE;
+ stream->tnstream->istream->super = (stream->tnstream);
+
+ // Initialize data elements of TREE stream
+ //
+ stream->tnstream->ctns = stream;
+
+ // Initialize data elements of the COMMON TREE NODE stream
+ //
+ stream->super = NULL;
+ stream->uniqueNavigationNodes = ANTLR3_FALSE;
+ stream->markers = NULL;
+ stream->nodeStack = antlr3StackNew(INITIAL_CALL_STACK_SIZE);
+
+ // Create the node list map
+ //
+ if (hint == 0)
+ {
+ hint = DEFAULT_INITIAL_BUFFER_SIZE;
+ }
+ stream->nodes = antlr3VectorNew(hint);
+ stream->p = -1;
+
+ // Install the navigation nodes
+ //
+ antlr3SetCTAPI(&(stream->UP));
+ antlr3SetCTAPI(&(stream->DOWN));
+ antlr3SetCTAPI(&(stream->EOF_NODE));
+ antlr3SetCTAPI(&(stream->INVALID_NODE));
+
+ token = antlr3CommonTokenNew(ANTLR3_TOKEN_UP);
+ token->strFactory = strFactory;
+ token->textState = ANTLR3_TEXT_CHARP;
+ token->tokText.chars = (pANTLR3_UCHAR)"UP";
+ stream->UP.token = token;
+
+ token = antlr3CommonTokenNew(ANTLR3_TOKEN_DOWN);
+ token->strFactory = strFactory;
+ token->textState = ANTLR3_TEXT_CHARP;
+ token->tokText.chars = (pANTLR3_UCHAR)"DOWN";
+ stream->DOWN.token = token;
+
+ token = antlr3CommonTokenNew(ANTLR3_TOKEN_EOF);
+ token->strFactory = strFactory;
+ token->textState = ANTLR3_TEXT_CHARP;
+ token->tokText.chars = (pANTLR3_UCHAR)"EOF";
+ stream->EOF_NODE.token = token;
+
+ token = antlr3CommonTokenNew(ANTLR3_TOKEN_INVALID);
+ token->strFactory = strFactory;
+ token->textState = ANTLR3_TEXT_CHARP;
+ token->tokText.chars = (pANTLR3_UCHAR)"INVALID";
+ stream->INVALID_NODE.token = token;
+
+
+ return stream;
+}
+
+/// Free up any resources that belong to this common tree node stream.
+///
+static void antlr3CommonTreeNodeStreamFree (pANTLR3_COMMON_TREE_NODE_STREAM ctns)
+{
+
+ // If this is a rewrting stream, then certain resources
+ // belong to the originating node stream and we do not
+ // free them here.
+ //
+ if (ctns->isRewriter != ANTLR3_TRUE)
+ {
+ ctns->adaptor ->free (ctns->adaptor);
+
+ if (ctns->nodeStack != NULL)
+ {
+ ctns->nodeStack->free(ctns->nodeStack);
+ }
+
+ ANTLR3_FREE(ctns->INVALID_NODE.token);
+ ANTLR3_FREE(ctns->EOF_NODE.token);
+ ANTLR3_FREE(ctns->DOWN.token);
+ ANTLR3_FREE(ctns->UP.token);
+ }
+
+ if (ctns->nodes != NULL)
+ {
+ ctns->nodes ->free (ctns->nodes);
+ }
+ ctns->tnstream->istream ->free (ctns->tnstream->istream);
+ ctns->tnstream ->free (ctns->tnstream);
+
+
+ ANTLR3_FREE(ctns);
+}
+
+// ------------------------------------------------------------------------------
+// Local helpers
+//
+
+/// Walk and fill the tree node buffer from the root tree
+///
+static void
+fillBufferRoot(pANTLR3_COMMON_TREE_NODE_STREAM ctns)
+{
+ // Call the generic buffer routine with the root as the
+ // argument
+ //
+ fillBuffer(ctns, ctns->root);
+ ctns->p = 0; // Indicate we are at buffer start
+}
+
+/// Walk tree with depth-first-search and fill nodes buffer.
+/// Don't add in DOWN, UP nodes if the supplied tree is a list (t is isNilNode)
+// such as the root tree is.
+///
+static void
+fillBuffer(pANTLR3_COMMON_TREE_NODE_STREAM ctns, pANTLR3_BASE_TREE t)
+{
+ ANTLR3_BOOLEAN nilNode;
+ ANTLR3_UINT32 nCount;
+ ANTLR3_UINT32 c;
+
+ nilNode = ctns->adaptor->isNilNode(ctns->adaptor, t);
+
+ // If the supplied node is not a nil (list) node then we
+ // add in the node itself to the vector
+ //
+ if (nilNode == ANTLR3_FALSE)
+ {
+ ctns->nodes->add(ctns->nodes, t, NULL);
+ }
+
+ // Only add a DOWN node if the tree is not a nil tree and
+ // the tree does have children.
+ //
+ nCount = t->getChildCount(t);
+
+ if (nilNode == ANTLR3_FALSE && nCount>0)
+ {
+ ctns->addNavigationNode(ctns, ANTLR3_TOKEN_DOWN);
+ }
+
+ // We always add any children the tree contains, which is
+ // a recursive call to this function, which will cause similar
+ // recursion and implement a depth first addition
+ //
+ for (c = 0; c < nCount; c++)
+ {
+ fillBuffer(ctns, ctns->adaptor->getChild(ctns->adaptor, t, c));
+ }
+
+ // If the tree had children and was not a nil (list) node, then we
+ // we need to add an UP node here to match the DOWN node
+ //
+ if (nilNode == ANTLR3_FALSE && nCount > 0)
+ {
+ ctns->addNavigationNode(ctns, ANTLR3_TOKEN_UP);
+ }
+}
+
+
+// ------------------------------------------------------------------------------
+// Interface functions
+//
+
+/// Reset the input stream to the start of the input nodes.
+///
+static void
+reset (pANTLR3_COMMON_TREE_NODE_STREAM ctns)
+{
+ if (ctns->p != -1)
+ {
+ ctns->p = 0;
+ }
+ ctns->tnstream->istream->lastMarker = 0;
+
+
+ // Free and reset the node stack only if this is not
+ // a rewriter, which is going to reuse the originating
+ // node streams node stack
+ //
+ if (ctns->isRewriter != ANTLR3_TRUE)
+ {
+ if (ctns->nodeStack != NULL)
+ {
+ ctns->nodeStack->free(ctns->nodeStack);
+ ctns->nodeStack = antlr3StackNew(INITIAL_CALL_STACK_SIZE);
+ }
+ }
+}
+
+
+static pANTLR3_BASE_TREE
+LB(pANTLR3_TREE_NODE_STREAM tns, ANTLR3_INT32 k)
+{
+ if ( k==0)
+ {
+ return &(tns->ctns->INVALID_NODE.baseTree);
+ }
+
+ if ( (tns->ctns->p - k) < 0)
+ {
+ return &(tns->ctns->INVALID_NODE.baseTree);
+ }
+
+ return tns->ctns->nodes->get(tns->ctns->nodes, tns->ctns->p - k);
+}
+
+/// Get tree node at current input pointer + i ahead where i=1 is next node.
+/// i<0 indicates nodes in the past. So -1 is previous node and -2 is
+/// two nodes ago. LT(0) is undefined. For i>=n, return null.
+/// Return null for LT(0) and any index that results in an absolute address
+/// that is negative.
+///
+/// This is analogous to the _LT() method of the TokenStream, but this
+/// returns a tree node instead of a token. Makes code gen identical
+/// for both parser and tree grammars. :)
+///
+static pANTLR3_BASE_TREE
+_LT (pANTLR3_TREE_NODE_STREAM tns, ANTLR3_INT32 k)
+{
+ if (tns->ctns->p == -1)
+ {
+ fillBufferRoot(tns->ctns);
+ }
+
+ if (k < 0)
+ {
+ return LB(tns, -k);
+ }
+ else if (k == 0)
+ {
+ return &(tns->ctns->INVALID_NODE.baseTree);
+ }
+
+ // k was a legitimate request,
+ //
+ if (( tns->ctns->p + k - 1) >= (ANTLR3_INT32)(tns->ctns->nodes->count))
+ {
+ return &(tns->ctns->EOF_NODE.baseTree);
+ }
+
+ return tns->ctns->nodes->get(tns->ctns->nodes, tns->ctns->p + k - 1);
+}
+
+/// Where is this stream pulling nodes from? This is not the name, but
+/// the object that provides node objects.
+///
+static pANTLR3_BASE_TREE
+getTreeSource (pANTLR3_TREE_NODE_STREAM tns)
+{
+ return tns->ctns->root;
+}
+
+/// Consume the next node from the input stream
+///
+static void
+consume (pANTLR3_INT_STREAM is)
+{
+ pANTLR3_TREE_NODE_STREAM tns;
+ pANTLR3_COMMON_TREE_NODE_STREAM ctns;
+
+ tns = (pANTLR3_TREE_NODE_STREAM)(is->super);
+ ctns = tns->ctns;
+
+ if (ctns->p == -1)
+ {
+ fillBufferRoot(ctns);
+ }
+ ctns->p++;
+}
+
+static ANTLR3_UINT32
+_LA (pANTLR3_INT_STREAM is, ANTLR3_INT32 i)
+{
+ pANTLR3_TREE_NODE_STREAM tns;
+ pANTLR3_BASE_TREE t;
+
+ tns = (pANTLR3_TREE_NODE_STREAM)(is->super);
+
+ // Ask LT for the 'token' at that position
+ //
+ t = tns->_LT(tns, i);
+
+ if (t == NULL)
+ {
+ return ANTLR3_TOKEN_INVALID;
+ }
+
+ // Token node was there so return the type of it
+ //
+ return t->getType(t);
+}
+
+/// Mark the state of the input stream so that we can come back to it
+/// after a syntactic predicate and so on.
+///
+static ANTLR3_MARKER
+mark (pANTLR3_INT_STREAM is)
+{
+ pANTLR3_TREE_NODE_STREAM tns;
+ pANTLR3_COMMON_TREE_NODE_STREAM ctns;
+
+ tns = (pANTLR3_TREE_NODE_STREAM)(is->super);
+ ctns = tns->ctns;
+
+ if (tns->ctns->p == -1)
+ {
+ fillBufferRoot(tns->ctns);
+ }
+
+ // Return the current mark point
+ //
+ ctns->tnstream->istream->lastMarker = ctns->tnstream->istream->index(ctns->tnstream->istream);
+
+ return ctns->tnstream->istream->lastMarker;
+}
+
+static void
+release (pANTLR3_INT_STREAM is, ANTLR3_MARKER marker)
+{
+}
+
+/// Rewind the current state of the tree walk to the state it
+/// was in when mark() was called and it returned marker. Also,
+/// wipe out the lookahead which will force reloading a few nodes
+/// but it is better than making a copy of the lookahead buffer
+/// upon mark().
+///
+static void
+rewindMark (pANTLR3_INT_STREAM is, ANTLR3_MARKER marker)
+{
+ is->seek(is, marker);
+}
+
+static void
+rewindLast (pANTLR3_INT_STREAM is)
+{
+ is->seek(is, is->lastMarker);
+}
+
+/// consume() ahead until we hit index. Can't just jump ahead--must
+/// spit out the navigation nodes.
+///
+static void
+seek (pANTLR3_INT_STREAM is, ANTLR3_MARKER index)
+{
+ pANTLR3_TREE_NODE_STREAM tns;
+ pANTLR3_COMMON_TREE_NODE_STREAM ctns;
+
+ tns = (pANTLR3_TREE_NODE_STREAM)(is->super);
+ ctns = tns->ctns;
+
+ ctns->p = ANTLR3_UINT32_CAST(index);
+}
+
+static ANTLR3_MARKER
+tindex (pANTLR3_INT_STREAM is)
+{
+ pANTLR3_TREE_NODE_STREAM tns;
+ pANTLR3_COMMON_TREE_NODE_STREAM ctns;
+
+ tns = (pANTLR3_TREE_NODE_STREAM)(is->super);
+ ctns = tns->ctns;
+
+ return (ANTLR3_MARKER)(ctns->p);
+}
+
+/// Expensive to compute the size of the whole tree while parsing.
+/// This method only returns how much input has been seen so far. So
+/// after parsing it returns true size.
+///
+static ANTLR3_UINT32
+size (pANTLR3_INT_STREAM is)
+{
+ pANTLR3_TREE_NODE_STREAM tns;
+ pANTLR3_COMMON_TREE_NODE_STREAM ctns;
+
+ tns = (pANTLR3_TREE_NODE_STREAM)(is->super);
+ ctns = tns->ctns;
+
+ if (ctns->p == -1)
+ {
+ fillBufferRoot(ctns);
+ }
+
+ return ctns->nodes->size(ctns->nodes);
+}
+
+/// As we flatten the tree, we use UP, DOWN nodes to represent
+/// the tree structure. When debugging we need unique nodes
+/// so instantiate new ones when uniqueNavigationNodes is true.
+///
+static void
+addNavigationNode (pANTLR3_COMMON_TREE_NODE_STREAM ctns, ANTLR3_UINT32 ttype)
+{
+ pANTLR3_BASE_TREE node;
+
+ node = NULL;
+
+ if (ttype == ANTLR3_TOKEN_DOWN)
+ {
+ if (ctns->hasUniqueNavigationNodes(ctns) == ANTLR3_TRUE)
+ {
+ node = ctns->newDownNode(ctns);
+ }
+ else
+ {
+ node = &(ctns->DOWN.baseTree);
+ }
+ }
+ else
+ {
+ if (ctns->hasUniqueNavigationNodes(ctns) == ANTLR3_TRUE)
+ {
+ node = ctns->newUpNode(ctns);
+ }
+ else
+ {
+ node = &(ctns->UP.baseTree);
+ }
+ }
+
+ // Now add the node we decided upon.
+ //
+ ctns->nodes->add(ctns->nodes, node, NULL);
+}
+
+
+static pANTLR3_BASE_TREE_ADAPTOR
+getTreeAdaptor (pANTLR3_TREE_NODE_STREAM tns)
+{
+ return tns->ctns->adaptor;
+}
+
+static ANTLR3_BOOLEAN
+hasUniqueNavigationNodes (pANTLR3_COMMON_TREE_NODE_STREAM ctns)
+{
+ return ctns->uniqueNavigationNodes;
+}
+
+static void
+setUniqueNavigationNodes (pANTLR3_TREE_NODE_STREAM tns, ANTLR3_BOOLEAN uniqueNavigationNodes)
+{
+ tns->ctns->uniqueNavigationNodes = uniqueNavigationNodes;
+}
+
+
+/// Print out the entire tree including DOWN/UP nodes. Uses
+/// a recursive walk. Mostly useful for testing as it yields
+/// the token types not text.
+///
+static pANTLR3_STRING
+toString (pANTLR3_TREE_NODE_STREAM tns)
+{
+
+ return tns->toStringSS(tns, tns->ctns->root, NULL);
+}
+
+static pANTLR3_STRING
+toStringSS (pANTLR3_TREE_NODE_STREAM tns, pANTLR3_BASE_TREE start, pANTLR3_BASE_TREE stop)
+{
+ pANTLR3_STRING buf;
+
+ buf = tns->ctns->stringFactory->newRaw(tns->ctns->stringFactory);
+
+ tns->toStringWork(tns, start, stop, buf);
+
+ return buf;
+}
+
+static void
+toStringWork (pANTLR3_TREE_NODE_STREAM tns, pANTLR3_BASE_TREE p, pANTLR3_BASE_TREE stop, pANTLR3_STRING buf)
+{
+
+ ANTLR3_UINT32 n;
+ ANTLR3_UINT32 c;
+
+ if (!p->isNilNode(p) )
+ {
+ pANTLR3_STRING text;
+
+ text = p->toString(p);
+
+ if (text == NULL)
+ {
+ text = tns->ctns->stringFactory->newRaw(tns->ctns->stringFactory);
+
+ text->addc (text, ' ');
+ text->addi (text, p->getType(p));
+ }
+
+ buf->appendS(buf, text);
+ }
+
+ if (p == stop)
+ {
+ return; /* Finished */
+ }
+
+ n = p->getChildCount(p);
+
+ if (n > 0 && ! p->isNilNode(p) )
+ {
+ buf->addc (buf, ' ');
+ buf->addi (buf, ANTLR3_TOKEN_DOWN);
+ }
+
+ for (c = 0; c<n ; c++)
+ {
+ pANTLR3_BASE_TREE child;
+
+ child = p->getChild(p, c);
+ tns->toStringWork(tns, child, stop, buf);
+ }
+
+ if (n > 0 && ! p->isNilNode(p) )
+ {
+ buf->addc (buf, ' ');
+ buf->addi (buf, ANTLR3_TOKEN_UP);
+ }
+}
+
+static ANTLR3_UINT32
+getLookaheadSize (pANTLR3_COMMON_TREE_NODE_STREAM ctns)
+{
+ return ctns->tail < ctns->head
+ ? (ctns->lookAheadLength - ctns->head + ctns->tail)
+ : (ctns->tail - ctns->head);
+}
+
+static pANTLR3_BASE_TREE
+newDownNode (pANTLR3_COMMON_TREE_NODE_STREAM ctns)
+{
+ pANTLR3_COMMON_TREE dNode;
+ pANTLR3_COMMON_TOKEN token;
+
+ token = antlr3CommonTokenNew(ANTLR3_TOKEN_DOWN);
+ token->textState = ANTLR3_TEXT_CHARP;
+ token->tokText.chars = (pANTLR3_UCHAR)"DOWN";
+ dNode = antlr3CommonTreeNewFromToken(token);
+
+ return &(dNode->baseTree);
+}
+
+static pANTLR3_BASE_TREE
+newUpNode (pANTLR3_COMMON_TREE_NODE_STREAM ctns)
+{
+ pANTLR3_COMMON_TREE uNode;
+ pANTLR3_COMMON_TOKEN token;
+
+ token = antlr3CommonTokenNew(ANTLR3_TOKEN_UP);
+ token->textState = ANTLR3_TEXT_CHARP;
+ token->tokText.chars = (pANTLR3_UCHAR)"UP";
+ uNode = antlr3CommonTreeNewFromToken(token);
+
+ return &(uNode->baseTree);
+}
+
+/// Replace from start to stop child index of parent with t, which might
+/// be a list. Number of children may be different
+/// after this call. The stream is notified because it is walking the
+/// tree and might need to know you are monkey-ing with the underlying
+/// tree. Also, it might be able to modify the node stream to avoid
+/// re-streaming for future phases.
+///
+/// If parent is null, don't do anything; must be at root of overall tree.
+/// Can't replace whatever points to the parent externally. Do nothing.
+///
+static void
+replaceChildren (pANTLR3_TREE_NODE_STREAM tns, pANTLR3_BASE_TREE parent, ANTLR3_INT32 startChildIndex, ANTLR3_INT32 stopChildIndex, pANTLR3_BASE_TREE t)
+{
+ if (parent != NULL)
+ {
+ pANTLR3_BASE_TREE_ADAPTOR adaptor;
+ pANTLR3_COMMON_TREE_ADAPTOR cta;
+
+ adaptor = tns->getTreeAdaptor(tns);
+ cta = (pANTLR3_COMMON_TREE_ADAPTOR)(adaptor->super);
+
+ adaptor->replaceChildren(adaptor, parent, startChildIndex, stopChildIndex, t);
+ }
+}
+
+static pANTLR3_BASE_TREE
+get (pANTLR3_TREE_NODE_STREAM tns, ANTLR3_INT32 k)
+{
+ if (tns->ctns->p == -1)
+ {
+ fillBufferRoot(tns->ctns);
+ }
+
+ return tns->ctns->nodes->get(tns->ctns->nodes, k);
+}
+
+static void
+push (pANTLR3_COMMON_TREE_NODE_STREAM ctns, ANTLR3_INT32 index)
+{
+ ctns->nodeStack->push(ctns->nodeStack, ANTLR3_FUNC_PTR(ctns->p), NULL); // Save current index
+ ctns->tnstream->istream->seek(ctns->tnstream->istream, index);
+}
+
+static ANTLR3_INT32
+pop (pANTLR3_COMMON_TREE_NODE_STREAM ctns)
+{
+ ANTLR3_INT32 retVal;
+
+ retVal = ANTLR3_UINT32_CAST(ctns->nodeStack->pop(ctns->nodeStack));
+ ctns->tnstream->istream->seek(ctns->tnstream->istream, retVal);
+ return retVal;
+}