--- /dev/null
+/// \file\r
+/// Implementation of token/tree streams that are used by the\r
+/// tree re-write rules to manipulate the tokens and trees produced\r
+/// by rules that are subject to rewrite directives.\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 <antlr3rewritestreams.h>\r
+\r
+// Static support function forward declarations for the stream types.\r
+//\r
+static void reset (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream); \r
+static void add (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * el, void (ANTLR3_CDECL *freePtr)(void *));\r
+static void * next (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);\r
+static pANTLR3_BASE_TREE nextTree (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);\r
+static void * nextToken (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);\r
+static void * _next (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);\r
+static void * dupTok (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * el);\r
+static void * dupTree (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * el);\r
+static void * dupTreeNode (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * el);\r
+static pANTLR3_BASE_TREE toTree (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * element);\r
+static pANTLR3_BASE_TREE toTreeNode (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * element);\r
+static ANTLR3_BOOLEAN hasNext (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);\r
+static pANTLR3_BASE_TREE nextNode (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);\r
+static pANTLR3_BASE_TREE nextNodeNode (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);\r
+static pANTLR3_BASE_TREE nextNodeToken (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);\r
+static ANTLR3_UINT32 size (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);\r
+static void * getDescription (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);\r
+static void freeRS (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);\r
+static void expungeRS (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);\r
+\r
+\r
+// Place a now unused rewrite stream back on the rewrite stream pool\r
+// so we can reuse it if we need to.\r
+//\r
+static void\r
+freeRS (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)\r
+{\r
+ // Before placing the stream back in the pool, we\r
+ // need to clear any vector it has. This is so any\r
+ // free pointers that are associated with the\r
+ // entires are called.\r
+ //\r
+ if (stream->elements != NULL)\r
+ {\r
+ // Factory generated vectors can be returned to the\r
+ // vector factory for later reuse.\r
+ //\r
+ if (stream->elements->factoryMade == ANTLR3_TRUE)\r
+ {\r
+ pANTLR3_VECTOR_FACTORY factory = ((pANTLR3_COMMON_TREE_ADAPTOR)(stream->adaptor->super))->arboretum->vFactory;\r
+ factory->returnVector(factory, stream->elements);\r
+\r
+ stream->elements = NULL;\r
+ } \r
+ else\r
+ {\r
+ // Other vectors we clear and allow to be reused if they come off the\r
+ // rewrite stream free stack and are reused.\r
+ //\r
+ stream->elements->clear(stream->elements);\r
+ stream->freeElements = ANTLR3_TRUE;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ stream->freeElements = ANTLR3_FALSE; // Just in case\r
+ }\r
+\r
+ // Add the stream into the recognizer stream stack vector\r
+ // adding the stream memory free routine so that\r
+ // it is thrown away when the stack vector is destroyed\r
+ //\r
+ stream->rec->state->rStreams->add(stream->rec->state->rStreams, stream, (void(*)(void *))expungeRS);\r
+}\r
+\r
+/** Do special nilNode reuse detection for node streams.\r
+ */\r
+static void\r
+freeNodeRS(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)\r
+{\r
+ pANTLR3_BASE_TREE tree;\r
+\r
+ // Before placing the stream back in the pool, we\r
+ // need to clear any vector it has. This is so any\r
+ // free pointers that are associated with the\r
+ // entires are called. However, if this particular function is called\r
+ // then we know that the entries in the stream are definately\r
+ // tree nodes. Hence we check to see if any of them were nilNodes as\r
+ // if they were, we can reuse them.\r
+ //\r
+ if (stream->elements != NULL)\r
+ {\r
+ // We have some elements to traverse\r
+ //\r
+ ANTLR3_UINT32 i;\r
+\r
+ for (i = 1; i<= stream->elements->count; i++)\r
+ {\r
+ tree = (pANTLR3_BASE_TREE)(stream->elements->elements[i-1].element);\r
+ if (tree != NULL && tree->isNilNode(tree))\r
+ {\r
+ // Had to remove this for now, check is not comprehensive enough\r
+ // tree->reuse(tree);\r
+ }\r
+\r
+ }\r
+ // Factory generated vectors can be returned to the\r
+ // vector factory for later reuse.\r
+ //\r
+ if (stream->elements->factoryMade == ANTLR3_TRUE)\r
+ {\r
+ pANTLR3_VECTOR_FACTORY factory = ((pANTLR3_COMMON_TREE_ADAPTOR)(stream->adaptor->super))->arboretum->vFactory;\r
+ factory->returnVector(factory, stream->elements);\r
+\r
+ stream->elements = NULL;\r
+ } \r
+ else\r
+ {\r
+ stream->elements->clear(stream->elements);\r
+ stream->freeElements = ANTLR3_TRUE;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ if (stream->singleElement != NULL)\r
+ {\r
+ tree = (pANTLR3_BASE_TREE)(stream->singleElement);\r
+ if (tree->isNilNode(tree))\r
+ {\r
+ // Had to remove this for now, check is not comprehensive enough\r
+ // tree->reuse(tree);\r
+ }\r
+ }\r
+ stream->singleElement = NULL;\r
+ stream->freeElements = ANTLR3_FALSE; // Just in case\r
+ }\r
+\r
+ // Add the stream into the recognizer stream stack vector\r
+ // adding the stream memory free routine so that\r
+ // it is thrown away when the stack vector is destroyed\r
+ //\r
+ stream->rec->state->rStreams->add(stream->rec->state->rStreams, stream, (void(*)(void *))expungeRS);\r
+}\r
+static void\r
+expungeRS(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)\r
+{\r
+\r
+ if (stream->freeElements == ANTLR3_TRUE && stream->elements != NULL)\r
+ {\r
+ stream->elements->free(stream->elements);\r
+ }\r
+ ANTLR3_FREE(stream);\r
+}\r
+\r
+// Functions for creating streams\r
+//\r
+static pANTLR3_REWRITE_RULE_ELEMENT_STREAM \r
+antlr3RewriteRuleElementStreamNewAE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description)\r
+{\r
+ pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream;\r
+\r
+ // First - do we already have a rewrite stream that was returned\r
+ // to the pool? If we do, then we will just reuse it by resetting\r
+ // the generic interface.\r
+ //\r
+ if (rec->state->rStreams->count > 0)\r
+ {\r
+ // Remove the entry from the vector. We do not\r
+ // cause it to be freed by using remove.\r
+ //\r
+ stream = rec->state->rStreams->remove(rec->state->rStreams, rec->state->rStreams->count - 1);\r
+\r
+ // We found a stream we can reuse.\r
+ // If the stream had a vector, then it will have been cleared\r
+ // when the freeRS was called that put it in this stack\r
+ //\r
+ }\r
+ else\r
+ {\r
+ // Ok, we need to allocate a new one as there were none on the stack.\r
+ // First job is to create the memory we need.\r
+ //\r
+ stream = (pANTLR3_REWRITE_RULE_ELEMENT_STREAM) ANTLR3_MALLOC((size_t)(sizeof(ANTLR3_REWRITE_RULE_ELEMENT_STREAM)));\r
+\r
+ if (stream == NULL)\r
+ {\r
+ return NULL;\r
+ }\r
+ stream->elements = NULL;\r
+ stream->freeElements = ANTLR3_FALSE;\r
+ }\r
+\r
+ // Populate the generic interface\r
+ //\r
+ stream->rec = rec;\r
+ stream->reset = reset;\r
+ stream->add = add;\r
+ stream->next = next;\r
+ stream->nextTree = nextTree;\r
+ stream->nextNode = nextNode;\r
+ stream->nextToken = nextToken;\r
+ stream->_next = _next;\r
+ stream->hasNext = hasNext;\r
+ stream->size = size;\r
+ stream->getDescription = getDescription;\r
+ stream->toTree = toTree;\r
+ stream->free = freeRS;\r
+ stream->singleElement = NULL;\r
+\r
+ // Reset the stream to empty.\r
+ //\r
+\r
+ stream->cursor = 0;\r
+ stream->dirty = ANTLR3_FALSE;\r
+\r
+ // Install the description\r
+ //\r
+ stream->elementDescription = description;\r
+\r
+ // Install the adaptor\r
+ //\r
+ stream->adaptor = adaptor;\r
+\r
+ return stream;\r
+}\r
+\r
+static pANTLR3_REWRITE_RULE_ELEMENT_STREAM \r
+antlr3RewriteRuleElementStreamNewAEE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description, void * oneElement)\r
+{\r
+ pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream;\r
+\r
+ // First job is to create the memory we need.\r
+ //\r
+ stream = antlr3RewriteRuleElementStreamNewAE(adaptor, rec, description);\r
+\r
+ if (stream == NULL)\r
+ {\r
+ return NULL;\r
+ }\r
+\r
+ // Stream seems good so we need to add the supplied element\r
+ //\r
+ if (oneElement != NULL)\r
+ {\r
+ stream->add(stream, oneElement, NULL);\r
+ }\r
+ return stream;\r
+}\r
+\r
+static pANTLR3_REWRITE_RULE_ELEMENT_STREAM \r
+antlr3RewriteRuleElementStreamNewAEV(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description, pANTLR3_VECTOR vector)\r
+{\r
+ pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream;\r
+\r
+ // First job is to create the memory we need.\r
+ //\r
+ stream = antlr3RewriteRuleElementStreamNewAE(adaptor, rec, description);\r
+\r
+ if (stream == NULL)\r
+ {\r
+ return stream;\r
+ }\r
+\r
+ // Stream seems good so we need to install the vector we were\r
+ // given. We assume that someone else is going to free the\r
+ // vector.\r
+ //\r
+ if (stream->elements != NULL && stream->elements->factoryMade == ANTLR3_FALSE && stream->freeElements == ANTLR3_TRUE )\r
+ {\r
+ stream->elements->free(stream->elements);\r
+ }\r
+ stream->elements = vector;\r
+ stream->freeElements = ANTLR3_FALSE;\r
+ return stream;\r
+}\r
+\r
+// Token rewrite stream ...\r
+//\r
+ANTLR3_API pANTLR3_REWRITE_RULE_TOKEN_STREAM \r
+antlr3RewriteRuleTOKENStreamNewAE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description)\r
+{\r
+ pANTLR3_REWRITE_RULE_TOKEN_STREAM stream;\r
+\r
+ // First job is to create the memory we need.\r
+ //\r
+ stream = antlr3RewriteRuleElementStreamNewAE(adaptor, rec, description);\r
+\r
+ if (stream == NULL)\r
+ {\r
+ return stream;\r
+ }\r
+\r
+ // Install the token based overrides\r
+ //\r
+ stream->dup = dupTok;\r
+ stream->nextNode = nextNodeToken;\r
+\r
+ // No nextNode implementation for a token rewrite stream\r
+ //\r
+ return stream;\r
+}\r
+\r
+ANTLR3_API pANTLR3_REWRITE_RULE_TOKEN_STREAM \r
+antlr3RewriteRuleTOKENStreamNewAEE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description, void * oneElement)\r
+{\r
+ pANTLR3_REWRITE_RULE_TOKEN_STREAM stream;\r
+\r
+ // First job is to create the memory we need.\r
+ //\r
+ stream = antlr3RewriteRuleElementStreamNewAEE(adaptor, rec, description, oneElement);\r
+\r
+ // Install the token based overrides\r
+ //\r
+ stream->dup = dupTok;\r
+ stream->nextNode = nextNodeToken;\r
+\r
+ // No nextNode implementation for a token rewrite stream\r
+ //\r
+ return stream;\r
+}\r
+\r
+ANTLR3_API pANTLR3_REWRITE_RULE_TOKEN_STREAM \r
+antlr3RewriteRuleTOKENStreamNewAEV(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description, pANTLR3_VECTOR vector)\r
+{\r
+ pANTLR3_REWRITE_RULE_TOKEN_STREAM stream;\r
+\r
+ // First job is to create the memory we need.\r
+ //\r
+ stream = antlr3RewriteRuleElementStreamNewAEV(adaptor, rec, description, vector);\r
+\r
+ // Install the token based overrides\r
+ //\r
+ stream->dup = dupTok;\r
+ stream->nextNode = nextNodeToken;\r
+\r
+ // No nextNode implementation for a token rewrite stream\r
+ //\r
+ return stream;\r
+}\r
+\r
+// Subtree rewrite stream\r
+//\r
+ANTLR3_API pANTLR3_REWRITE_RULE_SUBTREE_STREAM \r
+antlr3RewriteRuleSubtreeStreamNewAE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description)\r
+{\r
+ pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream;\r
+\r
+ // First job is to create the memory we need.\r
+ //\r
+ stream = antlr3RewriteRuleElementStreamNewAE(adaptor, rec, description);\r
+\r
+ if (stream == NULL)\r
+ {\r
+ return stream;\r
+ }\r
+\r
+ // Install the subtree based overrides\r
+ //\r
+ stream->dup = dupTree;\r
+ stream->nextNode = nextNode;\r
+ stream->free = freeNodeRS;\r
+ return stream;\r
+\r
+}\r
+ANTLR3_API pANTLR3_REWRITE_RULE_SUBTREE_STREAM \r
+antlr3RewriteRuleSubtreeStreamNewAEE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description, void * oneElement)\r
+{\r
+ pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream;\r
+\r
+ // First job is to create the memory we need.\r
+ //\r
+ stream = antlr3RewriteRuleElementStreamNewAEE(adaptor, rec, description, oneElement);\r
+\r
+ if (stream == NULL)\r
+ {\r
+ return stream;\r
+ }\r
+\r
+ // Install the subtree based overrides\r
+ //\r
+ stream->dup = dupTree;\r
+ stream->nextNode = nextNode;\r
+ stream->free = freeNodeRS;\r
+\r
+ return stream;\r
+}\r
+\r
+ANTLR3_API pANTLR3_REWRITE_RULE_SUBTREE_STREAM \r
+antlr3RewriteRuleSubtreeStreamNewAEV(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description, pANTLR3_VECTOR vector)\r
+{\r
+ pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream;\r
+\r
+ // First job is to create the memory we need.\r
+ //\r
+ stream = antlr3RewriteRuleElementStreamNewAEV(adaptor, rec, description, vector);\r
+\r
+ if (stream == NULL)\r
+ {\r
+ return NULL;\r
+ }\r
+\r
+ // Install the subtree based overrides\r
+ //\r
+ stream->dup = dupTree;\r
+ stream->nextNode = nextNode;\r
+ stream->free = freeNodeRS;\r
+\r
+ return stream;\r
+}\r
+// Node rewrite stream ...\r
+//\r
+ANTLR3_API pANTLR3_REWRITE_RULE_NODE_STREAM \r
+antlr3RewriteRuleNODEStreamNewAE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description)\r
+{\r
+ pANTLR3_REWRITE_RULE_NODE_STREAM stream;\r
+\r
+ // First job is to create the memory we need.\r
+ //\r
+ stream = antlr3RewriteRuleElementStreamNewAE(adaptor, rec, description);\r
+\r
+ if (stream == NULL)\r
+ {\r
+ return stream;\r
+ }\r
+\r
+ // Install the node based overrides\r
+ //\r
+ stream->dup = dupTreeNode;\r
+ stream->toTree = toTreeNode;\r
+ stream->nextNode = nextNodeNode;\r
+ stream->free = freeNodeRS;\r
+\r
+ return stream;\r
+}\r
+\r
+ANTLR3_API pANTLR3_REWRITE_RULE_NODE_STREAM \r
+antlr3RewriteRuleNODEStreamNewAEE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description, void * oneElement)\r
+{\r
+ pANTLR3_REWRITE_RULE_NODE_STREAM stream;\r
+\r
+ // First job is to create the memory we need.\r
+ //\r
+ stream = antlr3RewriteRuleElementStreamNewAEE(adaptor, rec, description, oneElement);\r
+\r
+ // Install the node based overrides\r
+ //\r
+ stream->dup = dupTreeNode;\r
+ stream->toTree = toTreeNode;\r
+ stream->nextNode = nextNodeNode;\r
+ stream->free = freeNodeRS;\r
+\r
+ return stream;\r
+}\r
+\r
+ANTLR3_API pANTLR3_REWRITE_RULE_NODE_STREAM \r
+antlr3RewriteRuleNODEStreamNewAEV(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description, pANTLR3_VECTOR vector)\r
+{\r
+ pANTLR3_REWRITE_RULE_NODE_STREAM stream;\r
+\r
+ // First job is to create the memory we need.\r
+ //\r
+ stream = antlr3RewriteRuleElementStreamNewAEV(adaptor, rec, description, vector);\r
+\r
+ // Install the Node based overrides\r
+ //\r
+ stream->dup = dupTreeNode;\r
+ stream->toTree = toTreeNode;\r
+ stream->nextNode = nextNodeNode;\r
+ stream->free = freeNodeRS;\r
+ \r
+ return stream;\r
+}\r
+\r
+//----------------------------------------------------------------------\r
+// Static support functions \r
+\r
+/// Reset the condition of this stream so that it appears we have\r
+/// not consumed any of its elements. Elements themselves are untouched.\r
+///\r
+static void \r
+reset (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)\r
+{\r
+ stream->dirty = ANTLR3_TRUE;\r
+ stream->cursor = 0;\r
+}\r
+\r
+// Add a new pANTLR3_BASE_TREE to this stream\r
+//\r
+static void \r
+add (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * el, void (ANTLR3_CDECL *freePtr)(void *))\r
+{\r
+ if (el== NULL)\r
+ {\r
+ return;\r
+ }\r
+ // As we may be reusing a stream, we may already have allocated\r
+ // a rewrite stream vector. If we have then is will be empty if\r
+ // we have either zero or just one element in the rewrite stream\r
+ //\r
+ if (stream->elements != NULL && stream->elements->count > 0)\r
+ {\r
+ // We already have >1 entries in the stream. So we can just add this new element to the existing\r
+ // collection. \r
+ //\r
+ stream->elements->add(stream->elements, el, freePtr);\r
+ return;\r
+ }\r
+ if (stream->singleElement == NULL)\r
+ {\r
+ stream->singleElement = el;\r
+ return;\r
+ }\r
+\r
+ // If we got here then we had only the one element so far\r
+ // and we must now create a vector to hold a collection of them\r
+ //\r
+ if (stream->elements == NULL)\r
+ {\r
+ pANTLR3_VECTOR_FACTORY factory = ((pANTLR3_COMMON_TREE_ADAPTOR)(stream->adaptor->super))->arboretum->vFactory;\r
+\r
+ \r
+ stream->elements = factory->newVector(factory);\r
+ stream->freeElements = ANTLR3_TRUE; // We 'ummed it, so we play it son.\r
+ }\r
+ \r
+ stream->elements->add (stream->elements, stream->singleElement, freePtr);\r
+ stream->elements->add (stream->elements, el, freePtr);\r
+ stream->singleElement = NULL;\r
+\r
+ return;\r
+}\r
+\r
+/// Return the next element in the stream. If out of elements, throw\r
+/// an exception unless size()==1. If size is 1, then return elements[0].\r
+/// Return a duplicate node/subtree if stream is out of elements and\r
+/// size==1. If we've already used the element, dup (dirty bit set).\r
+///\r
+static pANTLR3_BASE_TREE\r
+nextTree(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream) \r
+{\r
+ ANTLR3_UINT32 n;\r
+ void * el;\r
+\r
+ n = stream->size(stream);\r
+\r
+ if ( stream->dirty || (stream->cursor >=n && n==1) ) \r
+ {\r
+ // if out of elements and size is 1, dup\r
+ //\r
+ el = stream->_next(stream);\r
+ return stream->dup(stream, el);\r
+ }\r
+\r
+ // test size above then fetch\r
+ //\r
+ el = stream->_next(stream);\r
+ return el;\r
+}\r
+\r
+/// Return the next element for a caller that wants just the token\r
+///\r
+static void *\r
+nextToken (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)\r
+{\r
+ return stream->_next(stream);\r
+}\r
+\r
+/// Return the next element in the stream. If out of elements, throw\r
+/// an exception unless size()==1. If size is 1, then return elements[0].\r
+///\r
+static void * \r
+next (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)\r
+{\r
+ ANTLR3_UINT32 s;\r
+\r
+ s = stream->size(stream);\r
+ if (stream->cursor >= s && s == 1)\r
+ {\r
+ pANTLR3_BASE_TREE el;\r
+\r
+ el = stream->_next(stream);\r
+\r
+ return stream->dup(stream, el);\r
+ }\r
+\r
+ return stream->_next(stream);\r
+}\r
+\r
+/// Do the work of getting the next element, making sure that it's\r
+/// a tree node or subtree. Deal with the optimization of single-\r
+/// element list versus list of size > 1. Throw an exception (or something similar)\r
+/// if the stream is empty or we're out of elements and size>1.\r
+/// You can override in a 'subclass' if necessary.\r
+///\r
+static void *\r
+_next (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)\r
+{\r
+ ANTLR3_UINT32 n;\r
+ pANTLR3_BASE_TREE t;\r
+\r
+ n = stream->size(stream);\r
+\r
+ if (n == 0)\r
+ {\r
+ // This means that the stream is empty\r
+ //\r
+ return NULL; // Caller must cope with this\r
+ }\r
+\r
+ // Traversed all the available elements already?\r
+ //\r
+ if (stream->cursor >= n)\r
+ {\r
+ if (n == 1)\r
+ {\r
+ // Special case when size is single element, it will just dup a lot\r
+ //\r
+ return stream->toTree(stream, stream->singleElement);\r
+ }\r
+\r
+ // Out of elements and the size is not 1, so we cannot assume\r
+ // that we just duplicate the entry n times (such as ID ent+ -> ^(ID ent)+)\r
+ // This means we ran out of elements earlier than was expected.\r
+ //\r
+ return NULL; // Caller must cope with this\r
+ }\r
+\r
+ // Elements available either for duping or just available\r
+ //\r
+ if (stream->singleElement != NULL)\r
+ {\r
+ stream->cursor++; // Cursor advances even for single element as this tells us to dup()\r
+ return stream->toTree(stream, stream->singleElement);\r
+ }\r
+\r
+ // More than just a single element so we extract it from the \r
+ // vector.\r
+ //\r
+ t = stream->toTree(stream, stream->elements->get(stream->elements, stream->cursor));\r
+ stream->cursor++;\r
+ return t;\r
+}\r
+\r
+#ifdef ANTLR3_WINDOWS\r
+#pragma warning(push)\r
+#pragma warning(disable : 4100)\r
+#endif\r
+/// When constructing trees, sometimes we need to dup a token or AST\r
+/// subtree. Dup'ing a token means just creating another AST node\r
+/// around it. For trees, you must call the adaptor.dupTree().\r
+///\r
+static void * \r
+dupTok (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * el)\r
+{\r
+ ANTLR3_FPRINTF(stderr, "dup() cannot be called on a token rewrite stream!!");\r
+ return NULL;\r
+}\r
+#ifdef ANTLR3_WINDOWS\r
+#pragma warning(pop)\r
+#endif\r
+\r
+/// When constructing trees, sometimes we need to dup a token or AST\r
+/// subtree. Dup'ing a token means just creating another AST node\r
+/// around it. For trees, you must call the adaptor.dupTree().\r
+///\r
+static void * \r
+dupTree (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * element)\r
+{\r
+ return stream->adaptor->dupNode(stream->adaptor, (pANTLR3_BASE_TREE)element);\r
+}\r
+\r
+#ifdef ANTLR3_WINDOWS\r
+#pragma warning(push)\r
+#pragma warning(disable : 4100)\r
+#endif\r
+/// When constructing trees, sometimes we need to dup a token or AST\r
+/// subtree. Dup'ing a token means just creating another AST node\r
+/// around it. For trees, you must call the adaptor.dupTree().\r
+///\r
+static void * \r
+dupTreeNode (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * element)\r
+{\r
+ ANTLR3_FPRINTF(stderr, "dup() cannot be called on a node rewrite stream!!!");\r
+ return NULL;\r
+}\r
+\r
+\r
+/// We don;t explicitly convert to a tree unless the call goes to \r
+/// nextTree, which means rewrites are heterogeneous \r
+///\r
+static pANTLR3_BASE_TREE \r
+toTree (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * element)\r
+{\r
+ return (pANTLR3_BASE_TREE)element;\r
+}\r
+#ifdef ANTLR3_WINDOWS\r
+#pragma warning(pop)\r
+#endif\r
+\r
+/// Ensure stream emits trees; tokens must be converted to AST nodes.\r
+/// AST nodes can be passed through unmolested.\r
+///\r
+#ifdef ANTLR3_WINDOWS\r
+#pragma warning(push)\r
+#pragma warning(disable : 4100)\r
+#endif\r
+\r
+static pANTLR3_BASE_TREE \r
+toTreeNode (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * element)\r
+{\r
+ return stream->adaptor->dupNode(stream->adaptor, (pANTLR3_BASE_TREE)element);\r
+}\r
+\r
+#ifdef ANTLR3_WINDOWS\r
+#pragma warning(pop)\r
+#endif\r
+\r
+/// Returns ANTLR3_TRUE if there is a next element available\r
+///\r
+static ANTLR3_BOOLEAN \r
+hasNext (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)\r
+{\r
+ if ( (stream->singleElement != NULL && stream->cursor < 1)\r
+ || (stream->elements != NULL && stream->cursor < stream->elements->size(stream->elements)))\r
+ {\r
+ return ANTLR3_TRUE;\r
+ }\r
+ else\r
+ {\r
+ return ANTLR3_FALSE;\r
+ }\r
+}\r
+\r
+/// Get the next token from the list and create a node for it\r
+/// This is the implementation for token streams.\r
+///\r
+static pANTLR3_BASE_TREE\r
+nextNodeToken(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)\r
+{\r
+ return stream->adaptor->create(stream->adaptor, stream->_next(stream));\r
+}\r
+\r
+static pANTLR3_BASE_TREE\r
+nextNodeNode(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)\r
+{\r
+ return stream->_next(stream);\r
+}\r
+\r
+/// Treat next element as a single node even if it's a subtree.\r
+/// This is used instead of next() when the result has to be a\r
+/// tree root node. Also prevents us from duplicating recently-added\r
+/// children; e.g., ^(type ID)+ adds ID to type and then 2nd iteration\r
+/// must dup the type node, but ID has been added.\r
+///\r
+/// Referencing to a rule result twice is ok; dup entire tree as\r
+/// we can't be adding trees; e.g., expr expr. \r
+///\r
+static pANTLR3_BASE_TREE \r
+nextNode (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)\r
+{\r
+\r
+ ANTLR3_UINT32 n;\r
+ pANTLR3_BASE_TREE el = stream->_next(stream);\r
+\r
+ n = stream->size(stream);\r
+ if (stream->dirty == ANTLR3_TRUE || (stream->cursor > n && n == 1))\r
+ {\r
+ // We are out of elements and the size is 1, which means we just \r
+ // dup the node that we have\r
+ //\r
+ return stream->adaptor->dupNode(stream->adaptor, el);\r
+ }\r
+\r
+ // We were not out of nodes, so the one we received is the one to return\r
+ //\r
+ return el;\r
+}\r
+\r
+/// Number of elements available in the stream\r
+///\r
+static ANTLR3_UINT32 \r
+size (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)\r
+{\r
+ ANTLR3_UINT32 n = 0;\r
+\r
+ /// Should be a count of one if singleElement is set. I copied this\r
+ /// logic from the java implementation, which I suspect is just guarding\r
+ /// against someone setting singleElement and forgetting to NULL it out\r
+ ///\r
+ if (stream->singleElement != NULL)\r
+ {\r
+ n = 1;\r
+ }\r
+ else\r
+ {\r
+ if (stream->elements != NULL)\r
+ {\r
+ return (ANTLR3_UINT32)(stream->elements->count);\r
+ }\r
+ }\r
+ return n;\r
+}\r
+\r
+/// Returns the description string if there is one available (check for NULL).\r
+///\r
+static void * \r
+getDescription (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)\r
+{\r
+ if (stream->elementDescription == NULL)\r
+ {\r
+ stream->elementDescription = "<unknown source>";\r
+ }\r
+\r
+ return stream->elementDescription;\r
+}\r