xref: /aosp_15_r20/external/antlr/runtime/C/src/antlr3rewritestreams.c (revision 16467b971bd3e2009fad32dd79016f2c7e421deb)
1*16467b97STreehugger Robot /// \file
2*16467b97STreehugger Robot /// Implementation of token/tree streams that are used by the
3*16467b97STreehugger Robot /// tree re-write rules to manipulate the tokens and trees produced
4*16467b97STreehugger Robot /// by rules that are subject to rewrite directives.
5*16467b97STreehugger Robot ///
6*16467b97STreehugger Robot 
7*16467b97STreehugger Robot // [The "BSD licence"]
8*16467b97STreehugger Robot // Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC
9*16467b97STreehugger Robot // http://www.temporal-wave.com
10*16467b97STreehugger Robot // http://www.linkedin.com/in/jimidle
11*16467b97STreehugger Robot //
12*16467b97STreehugger Robot // All rights reserved.
13*16467b97STreehugger Robot //
14*16467b97STreehugger Robot // Redistribution and use in source and binary forms, with or without
15*16467b97STreehugger Robot // modification, are permitted provided that the following conditions
16*16467b97STreehugger Robot // are met:
17*16467b97STreehugger Robot // 1. Redistributions of source code must retain the above copyright
18*16467b97STreehugger Robot //    notice, this list of conditions and the following disclaimer.
19*16467b97STreehugger Robot // 2. Redistributions in binary form must reproduce the above copyright
20*16467b97STreehugger Robot //    notice, this list of conditions and the following disclaimer in the
21*16467b97STreehugger Robot //    documentation and/or other materials provided with the distribution.
22*16467b97STreehugger Robot // 3. The name of the author may not be used to endorse or promote products
23*16467b97STreehugger Robot //    derived from this software without specific prior written permission.
24*16467b97STreehugger Robot //
25*16467b97STreehugger Robot // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
26*16467b97STreehugger Robot // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27*16467b97STreehugger Robot // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28*16467b97STreehugger Robot // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
29*16467b97STreehugger Robot // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30*16467b97STreehugger Robot // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31*16467b97STreehugger Robot // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32*16467b97STreehugger Robot // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33*16467b97STreehugger Robot // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34*16467b97STreehugger Robot // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35*16467b97STreehugger Robot 
36*16467b97STreehugger Robot #include    <antlr3rewritestreams.h>
37*16467b97STreehugger Robot 
38*16467b97STreehugger Robot // Static support function forward declarations for the stream types.
39*16467b97STreehugger Robot //
40*16467b97STreehugger Robot static	void				reset			(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);
41*16467b97STreehugger Robot static	void				add				(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * el, void (ANTLR3_CDECL *freePtr)(void *));
42*16467b97STreehugger Robot static	void *				next			(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);
43*16467b97STreehugger Robot static	pANTLR3_BASE_TREE	nextTree		(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);
44*16467b97STreehugger Robot static	void *				nextToken		(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);
45*16467b97STreehugger Robot static	void *				_next			(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);
46*16467b97STreehugger Robot static	void *				dupTok			(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * el);
47*16467b97STreehugger Robot static	void *				dupTree			(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * el);
48*16467b97STreehugger Robot static	void *				dupTreeNode		(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * el);
49*16467b97STreehugger Robot static	pANTLR3_BASE_TREE	toTree			(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * element);
50*16467b97STreehugger Robot static	pANTLR3_BASE_TREE	toTreeNode		(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * element);
51*16467b97STreehugger Robot static	ANTLR3_BOOLEAN		hasNext			(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);
52*16467b97STreehugger Robot static	pANTLR3_BASE_TREE	nextNode		(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);
53*16467b97STreehugger Robot static	pANTLR3_BASE_TREE	nextNodeNode	(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);
54*16467b97STreehugger Robot static	pANTLR3_BASE_TREE	nextNodeToken	(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);
55*16467b97STreehugger Robot static	ANTLR3_UINT32		size			(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);
56*16467b97STreehugger Robot static	void *				getDescription	(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);
57*16467b97STreehugger Robot static	void				freeRS			(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);
58*16467b97STreehugger Robot static	void				expungeRS		(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);
59*16467b97STreehugger Robot 
60*16467b97STreehugger Robot 
61*16467b97STreehugger Robot // Place a now unused rewrite stream back on the rewrite stream pool
62*16467b97STreehugger Robot // so we can reuse it if we need to.
63*16467b97STreehugger Robot //
64*16467b97STreehugger Robot static void
freeRS(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)65*16467b97STreehugger Robot freeRS	(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)
66*16467b97STreehugger Robot {
67*16467b97STreehugger Robot 	// Before placing the stream back in the pool, we
68*16467b97STreehugger Robot 	// need to clear any vector it has. This is so any
69*16467b97STreehugger Robot 	// free pointers that are associated with the
70*16467b97STreehugger Robot 	// entires are called.
71*16467b97STreehugger Robot 	//
72*16467b97STreehugger Robot 	if	(stream->elements != NULL)
73*16467b97STreehugger Robot 	{
74*16467b97STreehugger Robot 		// Factory generated vectors can be returned to the
75*16467b97STreehugger Robot 		// vector factory for later reuse.
76*16467b97STreehugger Robot 		//
77*16467b97STreehugger Robot 		if	(stream->elements->factoryMade == ANTLR3_TRUE)
78*16467b97STreehugger Robot 		{
79*16467b97STreehugger Robot 			pANTLR3_VECTOR_FACTORY factory = ((pANTLR3_COMMON_TREE_ADAPTOR)(stream->adaptor->super))->arboretum->vFactory;
80*16467b97STreehugger Robot 			factory->returnVector(factory, stream->elements);
81*16467b97STreehugger Robot 
82*16467b97STreehugger Robot 			stream->elements = NULL;
83*16467b97STreehugger Robot 		}
84*16467b97STreehugger Robot 		else
85*16467b97STreehugger Robot 		{
86*16467b97STreehugger Robot 			// Other vectors we clear and allow to be reused if they come off the
87*16467b97STreehugger Robot 			// rewrite stream free stack and are reused.
88*16467b97STreehugger Robot 			//
89*16467b97STreehugger Robot 			stream->elements->clear(stream->elements);
90*16467b97STreehugger Robot 			stream->freeElements = ANTLR3_TRUE;
91*16467b97STreehugger Robot 		}
92*16467b97STreehugger Robot 	}
93*16467b97STreehugger Robot 	else
94*16467b97STreehugger Robot 	{
95*16467b97STreehugger Robot 		stream->freeElements = ANTLR3_FALSE; // Just in case
96*16467b97STreehugger Robot 	}
97*16467b97STreehugger Robot 
98*16467b97STreehugger Robot 	// Add the stream into the recognizer stream stack vector
99*16467b97STreehugger Robot 	// adding the stream memory free routine so that
100*16467b97STreehugger Robot 	// it is thrown away when the stack vector is destroyed
101*16467b97STreehugger Robot 	//
102*16467b97STreehugger Robot 	stream->rec->state->rStreams->add(stream->rec->state->rStreams, stream, (void(*)(void *))expungeRS);
103*16467b97STreehugger Robot }
104*16467b97STreehugger Robot 
105*16467b97STreehugger Robot /** Do special nilNode reuse detection for node streams.
106*16467b97STreehugger Robot  */
107*16467b97STreehugger Robot static void
freeNodeRS(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)108*16467b97STreehugger Robot freeNodeRS(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)
109*16467b97STreehugger Robot {
110*16467b97STreehugger Robot     pANTLR3_BASE_TREE tree;
111*16467b97STreehugger Robot 
112*16467b97STreehugger Robot     // Before placing the stream back in the pool, we
113*16467b97STreehugger Robot 	// need to clear any vector it has. This is so any
114*16467b97STreehugger Robot 	// free pointers that are associated with the
115*16467b97STreehugger Robot 	// entires are called. However, if this particular function is called
116*16467b97STreehugger Robot     // then we know that the entries in the stream are definately
117*16467b97STreehugger Robot     // tree nodes. Hence we check to see if any of them were nilNodes as
118*16467b97STreehugger Robot     // if they were, we can reuse them.
119*16467b97STreehugger Robot 	//
120*16467b97STreehugger Robot 	if	(stream->elements != NULL)
121*16467b97STreehugger Robot 	{
122*16467b97STreehugger Robot         // We have some elements to traverse
123*16467b97STreehugger Robot         //
124*16467b97STreehugger Robot         ANTLR3_UINT32 i;
125*16467b97STreehugger Robot 
126*16467b97STreehugger Robot         for (i = 1; i<= stream->elements->count; i++)
127*16467b97STreehugger Robot         {
128*16467b97STreehugger Robot             tree = (pANTLR3_BASE_TREE)(stream->elements->elements[i-1].element);
129*16467b97STreehugger Robot             if  (tree != NULL && tree->isNilNode(tree))
130*16467b97STreehugger Robot             {
131*16467b97STreehugger Robot                 // Had to remove this for now, check is not comprehensive enough
132*16467b97STreehugger Robot                 // tree->reuse(tree);
133*16467b97STreehugger Robot             }
134*16467b97STreehugger Robot 
135*16467b97STreehugger Robot         }
136*16467b97STreehugger Robot 		// Factory generated vectors can be returned to the
137*16467b97STreehugger Robot 		// vector factory for later reuse.
138*16467b97STreehugger Robot 		//
139*16467b97STreehugger Robot 		if	(stream->elements->factoryMade == ANTLR3_TRUE)
140*16467b97STreehugger Robot 		{
141*16467b97STreehugger Robot 			pANTLR3_VECTOR_FACTORY factory = ((pANTLR3_COMMON_TREE_ADAPTOR)(stream->adaptor->super))->arboretum->vFactory;
142*16467b97STreehugger Robot 			factory->returnVector(factory, stream->elements);
143*16467b97STreehugger Robot 
144*16467b97STreehugger Robot 			stream->elements = NULL;
145*16467b97STreehugger Robot 		}
146*16467b97STreehugger Robot 		else
147*16467b97STreehugger Robot 		{
148*16467b97STreehugger Robot 			stream->elements->clear(stream->elements);
149*16467b97STreehugger Robot 			stream->freeElements = ANTLR3_TRUE;
150*16467b97STreehugger Robot 		}
151*16467b97STreehugger Robot 	}
152*16467b97STreehugger Robot 	else
153*16467b97STreehugger Robot 	{
154*16467b97STreehugger Robot         if  (stream->singleElement != NULL)
155*16467b97STreehugger Robot         {
156*16467b97STreehugger Robot             tree = (pANTLR3_BASE_TREE)(stream->singleElement);
157*16467b97STreehugger Robot             if  (tree->isNilNode(tree))
158*16467b97STreehugger Robot             {
159*16467b97STreehugger Robot                 // Had to remove this for now, check is not comprehensive enough
160*16467b97STreehugger Robot               //   tree->reuse(tree);
161*16467b97STreehugger Robot             }
162*16467b97STreehugger Robot         }
163*16467b97STreehugger Robot         stream->singleElement = NULL;
164*16467b97STreehugger Robot 		stream->freeElements = ANTLR3_FALSE; // Just in case
165*16467b97STreehugger Robot 	}
166*16467b97STreehugger Robot 
167*16467b97STreehugger Robot 	// Add the stream into the recognizer stream stack vector
168*16467b97STreehugger Robot 	// adding the stream memory free routine so that
169*16467b97STreehugger Robot 	// it is thrown away when the stack vector is destroyed
170*16467b97STreehugger Robot 	//
171*16467b97STreehugger Robot 	stream->rec->state->rStreams->add(stream->rec->state->rStreams, stream, (void(*)(void *))expungeRS);
172*16467b97STreehugger Robot }
173*16467b97STreehugger Robot static void
expungeRS(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)174*16467b97STreehugger Robot expungeRS(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)
175*16467b97STreehugger Robot {
176*16467b97STreehugger Robot 
177*16467b97STreehugger Robot 	if (stream->freeElements == ANTLR3_TRUE && stream->elements != NULL)
178*16467b97STreehugger Robot 	{
179*16467b97STreehugger Robot 		stream->elements->free(stream->elements);
180*16467b97STreehugger Robot 	}
181*16467b97STreehugger Robot 	ANTLR3_FREE(stream);
182*16467b97STreehugger Robot }
183*16467b97STreehugger Robot 
184*16467b97STreehugger Robot // Functions for creating streams
185*16467b97STreehugger Robot //
186*16467b97STreehugger Robot static  pANTLR3_REWRITE_RULE_ELEMENT_STREAM
antlr3RewriteRuleElementStreamNewAE(pANTLR3_BASE_TREE_ADAPTOR adaptor,pANTLR3_BASE_RECOGNIZER rec,pANTLR3_UINT8 description)187*16467b97STreehugger Robot antlr3RewriteRuleElementStreamNewAE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description)
188*16467b97STreehugger Robot {
189*16467b97STreehugger Robot 	pANTLR3_REWRITE_RULE_ELEMENT_STREAM	stream;
190*16467b97STreehugger Robot 
191*16467b97STreehugger Robot 	// First - do we already have a rewrite stream that was returned
192*16467b97STreehugger Robot 	// to the pool? If we do, then we will just reuse it by resetting
193*16467b97STreehugger Robot 	// the generic interface.
194*16467b97STreehugger Robot 	//
195*16467b97STreehugger Robot 	if	(rec->state->rStreams->count > 0)
196*16467b97STreehugger Robot 	{
197*16467b97STreehugger Robot 		// Remove the entry from the vector. We do not
198*16467b97STreehugger Robot 		// cause it to be freed by using remove.
199*16467b97STreehugger Robot 		//
200*16467b97STreehugger Robot 		stream = (pANTLR3_REWRITE_RULE_ELEMENT_STREAM)rec->state->rStreams->remove(rec->state->rStreams, rec->state->rStreams->count - 1);
201*16467b97STreehugger Robot 
202*16467b97STreehugger Robot 		// We found a stream we can reuse.
203*16467b97STreehugger Robot 		// If the stream had a vector, then it will have been cleared
204*16467b97STreehugger Robot 		// when the freeRS was called that put it in this stack
205*16467b97STreehugger Robot 		//
206*16467b97STreehugger Robot 	}
207*16467b97STreehugger Robot 	else
208*16467b97STreehugger Robot 	{
209*16467b97STreehugger Robot 		// Ok, we need to allocate a new one as there were none on the stack.
210*16467b97STreehugger Robot 		// First job is to create the memory we need.
211*16467b97STreehugger Robot 		//
212*16467b97STreehugger Robot 		stream	= (pANTLR3_REWRITE_RULE_ELEMENT_STREAM) ANTLR3_MALLOC((size_t)(sizeof(ANTLR3_REWRITE_RULE_ELEMENT_STREAM)));
213*16467b97STreehugger Robot 
214*16467b97STreehugger Robot 		if	(stream == NULL)
215*16467b97STreehugger Robot 		{
216*16467b97STreehugger Robot 			return	NULL;
217*16467b97STreehugger Robot 		}
218*16467b97STreehugger Robot 		stream->elements		= NULL;
219*16467b97STreehugger Robot 		stream->freeElements	= ANTLR3_FALSE;
220*16467b97STreehugger Robot 	}
221*16467b97STreehugger Robot 
222*16467b97STreehugger Robot 	// Populate the generic interface
223*16467b97STreehugger Robot 	//
224*16467b97STreehugger Robot 	stream->rec				= rec;
225*16467b97STreehugger Robot 	stream->reset			= reset;
226*16467b97STreehugger Robot 	stream->add				= add;
227*16467b97STreehugger Robot 	stream->next			= next;
228*16467b97STreehugger Robot 	stream->nextTree		= nextTree;
229*16467b97STreehugger Robot 	stream->nextNode		= nextNode;
230*16467b97STreehugger Robot 	stream->nextToken		= nextToken;
231*16467b97STreehugger Robot 	stream->_next			= _next;
232*16467b97STreehugger Robot 	stream->hasNext			= hasNext;
233*16467b97STreehugger Robot 	stream->size			= size;
234*16467b97STreehugger Robot 	stream->getDescription  = getDescription;
235*16467b97STreehugger Robot 	stream->toTree			= toTree;
236*16467b97STreehugger Robot 	stream->free			= freeRS;
237*16467b97STreehugger Robot 	stream->singleElement	= NULL;
238*16467b97STreehugger Robot 
239*16467b97STreehugger Robot 	// Reset the stream to empty.
240*16467b97STreehugger Robot 	//
241*16467b97STreehugger Robot 
242*16467b97STreehugger Robot 	stream->cursor			= 0;
243*16467b97STreehugger Robot 	stream->dirty			= ANTLR3_FALSE;
244*16467b97STreehugger Robot 
245*16467b97STreehugger Robot 	// Install the description
246*16467b97STreehugger Robot 	//
247*16467b97STreehugger Robot 	stream->elementDescription	= description;
248*16467b97STreehugger Robot 
249*16467b97STreehugger Robot 	// Install the adaptor
250*16467b97STreehugger Robot 	//
251*16467b97STreehugger Robot 	stream->adaptor		= adaptor;
252*16467b97STreehugger Robot 
253*16467b97STreehugger Robot 	return stream;
254*16467b97STreehugger Robot }
255*16467b97STreehugger Robot 
256*16467b97STreehugger Robot static pANTLR3_REWRITE_RULE_ELEMENT_STREAM
antlr3RewriteRuleElementStreamNewAEE(pANTLR3_BASE_TREE_ADAPTOR adaptor,pANTLR3_BASE_RECOGNIZER rec,pANTLR3_UINT8 description,void * oneElement)257*16467b97STreehugger Robot antlr3RewriteRuleElementStreamNewAEE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description, void * oneElement)
258*16467b97STreehugger Robot {
259*16467b97STreehugger Robot 	pANTLR3_REWRITE_RULE_ELEMENT_STREAM	stream;
260*16467b97STreehugger Robot 
261*16467b97STreehugger Robot 	// First job is to create the memory we need.
262*16467b97STreehugger Robot 	//
263*16467b97STreehugger Robot 	stream	= antlr3RewriteRuleElementStreamNewAE(adaptor, rec, description);
264*16467b97STreehugger Robot 
265*16467b97STreehugger Robot 	if (stream == NULL)
266*16467b97STreehugger Robot 	{
267*16467b97STreehugger Robot 		return NULL;
268*16467b97STreehugger Robot 	}
269*16467b97STreehugger Robot 
270*16467b97STreehugger Robot 	// Stream seems good so we need to add the supplied element
271*16467b97STreehugger Robot 	//
272*16467b97STreehugger Robot 	if	(oneElement != NULL)
273*16467b97STreehugger Robot 	{
274*16467b97STreehugger Robot 		stream->add(stream, oneElement, NULL);
275*16467b97STreehugger Robot 	}
276*16467b97STreehugger Robot 	return stream;
277*16467b97STreehugger Robot }
278*16467b97STreehugger Robot 
279*16467b97STreehugger Robot static pANTLR3_REWRITE_RULE_ELEMENT_STREAM
antlr3RewriteRuleElementStreamNewAEV(pANTLR3_BASE_TREE_ADAPTOR adaptor,pANTLR3_BASE_RECOGNIZER rec,pANTLR3_UINT8 description,pANTLR3_VECTOR vector)280*16467b97STreehugger Robot antlr3RewriteRuleElementStreamNewAEV(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description, pANTLR3_VECTOR vector)
281*16467b97STreehugger Robot {
282*16467b97STreehugger Robot 	pANTLR3_REWRITE_RULE_ELEMENT_STREAM	stream;
283*16467b97STreehugger Robot 
284*16467b97STreehugger Robot 	// First job is to create the memory we need.
285*16467b97STreehugger Robot 	//
286*16467b97STreehugger Robot 	stream	= antlr3RewriteRuleElementStreamNewAE(adaptor, rec, description);
287*16467b97STreehugger Robot 
288*16467b97STreehugger Robot 	if (stream == NULL)
289*16467b97STreehugger Robot 	{
290*16467b97STreehugger Robot 		return stream;
291*16467b97STreehugger Robot 	}
292*16467b97STreehugger Robot 
293*16467b97STreehugger Robot 	// Stream seems good so we need to install the vector we were
294*16467b97STreehugger Robot 	// given. We assume that someone else is going to free the
295*16467b97STreehugger Robot 	// vector.
296*16467b97STreehugger Robot 	//
297*16467b97STreehugger Robot 	if	(stream->elements != NULL && stream->elements->factoryMade == ANTLR3_FALSE && stream->freeElements == ANTLR3_TRUE )
298*16467b97STreehugger Robot 	{
299*16467b97STreehugger Robot 		stream->elements->free(stream->elements);
300*16467b97STreehugger Robot 	}
301*16467b97STreehugger Robot 	stream->elements		= vector;
302*16467b97STreehugger Robot 	stream->freeElements	= ANTLR3_FALSE;
303*16467b97STreehugger Robot 	return stream;
304*16467b97STreehugger Robot }
305*16467b97STreehugger Robot 
306*16467b97STreehugger Robot // Token rewrite stream ...
307*16467b97STreehugger Robot //
308*16467b97STreehugger Robot ANTLR3_API pANTLR3_REWRITE_RULE_TOKEN_STREAM
antlr3RewriteRuleTOKENStreamNewAE(pANTLR3_BASE_TREE_ADAPTOR adaptor,pANTLR3_BASE_RECOGNIZER rec,pANTLR3_UINT8 description)309*16467b97STreehugger Robot antlr3RewriteRuleTOKENStreamNewAE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description)
310*16467b97STreehugger Robot {
311*16467b97STreehugger Robot 	pANTLR3_REWRITE_RULE_TOKEN_STREAM	stream;
312*16467b97STreehugger Robot 
313*16467b97STreehugger Robot 	// First job is to create the memory we need.
314*16467b97STreehugger Robot 	//
315*16467b97STreehugger Robot 	stream	= antlr3RewriteRuleElementStreamNewAE(adaptor, rec, description);
316*16467b97STreehugger Robot 
317*16467b97STreehugger Robot 	if (stream == NULL)
318*16467b97STreehugger Robot 	{
319*16467b97STreehugger Robot 		return stream;
320*16467b97STreehugger Robot 	}
321*16467b97STreehugger Robot 
322*16467b97STreehugger Robot 	// Install the token based overrides
323*16467b97STreehugger Robot 	//
324*16467b97STreehugger Robot 	stream->dup			= dupTok;
325*16467b97STreehugger Robot 	stream->nextNode	= nextNodeToken;
326*16467b97STreehugger Robot 
327*16467b97STreehugger Robot 	// No nextNode implementation for a token rewrite stream
328*16467b97STreehugger Robot 	//
329*16467b97STreehugger Robot 	return stream;
330*16467b97STreehugger Robot }
331*16467b97STreehugger Robot 
332*16467b97STreehugger Robot ANTLR3_API pANTLR3_REWRITE_RULE_TOKEN_STREAM
antlr3RewriteRuleTOKENStreamNewAEE(pANTLR3_BASE_TREE_ADAPTOR adaptor,pANTLR3_BASE_RECOGNIZER rec,pANTLR3_UINT8 description,void * oneElement)333*16467b97STreehugger Robot antlr3RewriteRuleTOKENStreamNewAEE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description, void * oneElement)
334*16467b97STreehugger Robot {
335*16467b97STreehugger Robot 	pANTLR3_REWRITE_RULE_TOKEN_STREAM	stream;
336*16467b97STreehugger Robot 
337*16467b97STreehugger Robot 	// First job is to create the memory we need.
338*16467b97STreehugger Robot 	//
339*16467b97STreehugger Robot 	stream	= antlr3RewriteRuleElementStreamNewAEE(adaptor, rec, description, oneElement);
340*16467b97STreehugger Robot 
341*16467b97STreehugger Robot 	// Install the token based overrides
342*16467b97STreehugger Robot 	//
343*16467b97STreehugger Robot 	stream->dup			= dupTok;
344*16467b97STreehugger Robot 	stream->nextNode	= nextNodeToken;
345*16467b97STreehugger Robot 
346*16467b97STreehugger Robot 	// No nextNode implementation for a token rewrite stream
347*16467b97STreehugger Robot 	//
348*16467b97STreehugger Robot 	return stream;
349*16467b97STreehugger Robot }
350*16467b97STreehugger Robot 
351*16467b97STreehugger Robot ANTLR3_API pANTLR3_REWRITE_RULE_TOKEN_STREAM
antlr3RewriteRuleTOKENStreamNewAEV(pANTLR3_BASE_TREE_ADAPTOR adaptor,pANTLR3_BASE_RECOGNIZER rec,pANTLR3_UINT8 description,pANTLR3_VECTOR vector)352*16467b97STreehugger Robot antlr3RewriteRuleTOKENStreamNewAEV(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description, pANTLR3_VECTOR vector)
353*16467b97STreehugger Robot {
354*16467b97STreehugger Robot 	pANTLR3_REWRITE_RULE_TOKEN_STREAM	stream;
355*16467b97STreehugger Robot 
356*16467b97STreehugger Robot 	// First job is to create the memory we need.
357*16467b97STreehugger Robot 	//
358*16467b97STreehugger Robot 	stream	= antlr3RewriteRuleElementStreamNewAEV(adaptor, rec, description, vector);
359*16467b97STreehugger Robot 
360*16467b97STreehugger Robot 	// Install the token based overrides
361*16467b97STreehugger Robot 	//
362*16467b97STreehugger Robot 	stream->dup			= dupTok;
363*16467b97STreehugger Robot 	stream->nextNode	= nextNodeToken;
364*16467b97STreehugger Robot 
365*16467b97STreehugger Robot 	// No nextNode implementation for a token rewrite stream
366*16467b97STreehugger Robot 	//
367*16467b97STreehugger Robot 	return stream;
368*16467b97STreehugger Robot }
369*16467b97STreehugger Robot 
370*16467b97STreehugger Robot // Subtree rewrite stream
371*16467b97STreehugger Robot //
372*16467b97STreehugger Robot ANTLR3_API pANTLR3_REWRITE_RULE_SUBTREE_STREAM
antlr3RewriteRuleSubtreeStreamNewAE(pANTLR3_BASE_TREE_ADAPTOR adaptor,pANTLR3_BASE_RECOGNIZER rec,pANTLR3_UINT8 description)373*16467b97STreehugger Robot antlr3RewriteRuleSubtreeStreamNewAE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description)
374*16467b97STreehugger Robot {
375*16467b97STreehugger Robot 	pANTLR3_REWRITE_RULE_SUBTREE_STREAM	stream;
376*16467b97STreehugger Robot 
377*16467b97STreehugger Robot 	// First job is to create the memory we need.
378*16467b97STreehugger Robot 	//
379*16467b97STreehugger Robot 	stream	= antlr3RewriteRuleElementStreamNewAE(adaptor, rec, description);
380*16467b97STreehugger Robot 
381*16467b97STreehugger Robot 	if (stream == NULL)
382*16467b97STreehugger Robot 	{
383*16467b97STreehugger Robot 		return stream;
384*16467b97STreehugger Robot 	}
385*16467b97STreehugger Robot 
386*16467b97STreehugger Robot 	// Install the subtree based overrides
387*16467b97STreehugger Robot 	//
388*16467b97STreehugger Robot 	stream->dup			= dupTree;
389*16467b97STreehugger Robot 	stream->nextNode	= nextNode;
390*16467b97STreehugger Robot     stream->free        = freeNodeRS;
391*16467b97STreehugger Robot 	return stream;
392*16467b97STreehugger Robot 
393*16467b97STreehugger Robot }
394*16467b97STreehugger Robot ANTLR3_API pANTLR3_REWRITE_RULE_SUBTREE_STREAM
antlr3RewriteRuleSubtreeStreamNewAEE(pANTLR3_BASE_TREE_ADAPTOR adaptor,pANTLR3_BASE_RECOGNIZER rec,pANTLR3_UINT8 description,void * oneElement)395*16467b97STreehugger Robot antlr3RewriteRuleSubtreeStreamNewAEE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description, void * oneElement)
396*16467b97STreehugger Robot {
397*16467b97STreehugger Robot 	pANTLR3_REWRITE_RULE_SUBTREE_STREAM	stream;
398*16467b97STreehugger Robot 
399*16467b97STreehugger Robot 	// First job is to create the memory we need.
400*16467b97STreehugger Robot 	//
401*16467b97STreehugger Robot 	stream	= antlr3RewriteRuleElementStreamNewAEE(adaptor, rec, description, oneElement);
402*16467b97STreehugger Robot 
403*16467b97STreehugger Robot 	if (stream == NULL)
404*16467b97STreehugger Robot 	{
405*16467b97STreehugger Robot 		return stream;
406*16467b97STreehugger Robot 	}
407*16467b97STreehugger Robot 
408*16467b97STreehugger Robot 	// Install the subtree based overrides
409*16467b97STreehugger Robot 	//
410*16467b97STreehugger Robot 	stream->dup			= dupTree;
411*16467b97STreehugger Robot 	stream->nextNode	= nextNode;
412*16467b97STreehugger Robot     stream->free        = freeNodeRS;
413*16467b97STreehugger Robot 
414*16467b97STreehugger Robot 	return stream;
415*16467b97STreehugger Robot }
416*16467b97STreehugger Robot 
417*16467b97STreehugger Robot ANTLR3_API pANTLR3_REWRITE_RULE_SUBTREE_STREAM
antlr3RewriteRuleSubtreeStreamNewAEV(pANTLR3_BASE_TREE_ADAPTOR adaptor,pANTLR3_BASE_RECOGNIZER rec,pANTLR3_UINT8 description,pANTLR3_VECTOR vector)418*16467b97STreehugger Robot antlr3RewriteRuleSubtreeStreamNewAEV(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description, pANTLR3_VECTOR vector)
419*16467b97STreehugger Robot {
420*16467b97STreehugger Robot 	pANTLR3_REWRITE_RULE_SUBTREE_STREAM	stream;
421*16467b97STreehugger Robot 
422*16467b97STreehugger Robot 	// First job is to create the memory we need.
423*16467b97STreehugger Robot 	//
424*16467b97STreehugger Robot 	stream	= antlr3RewriteRuleElementStreamNewAEV(adaptor, rec, description, vector);
425*16467b97STreehugger Robot 
426*16467b97STreehugger Robot 	if (stream == NULL)
427*16467b97STreehugger Robot 	{
428*16467b97STreehugger Robot 		return NULL;
429*16467b97STreehugger Robot 	}
430*16467b97STreehugger Robot 
431*16467b97STreehugger Robot 	// Install the subtree based overrides
432*16467b97STreehugger Robot 	//
433*16467b97STreehugger Robot 	stream->dup			= dupTree;
434*16467b97STreehugger Robot 	stream->nextNode	= nextNode;
435*16467b97STreehugger Robot     stream->free        = freeNodeRS;
436*16467b97STreehugger Robot 
437*16467b97STreehugger Robot 	return stream;
438*16467b97STreehugger Robot }
439*16467b97STreehugger Robot // Node rewrite stream ...
440*16467b97STreehugger Robot //
441*16467b97STreehugger Robot ANTLR3_API pANTLR3_REWRITE_RULE_NODE_STREAM
antlr3RewriteRuleNODEStreamNewAE(pANTLR3_BASE_TREE_ADAPTOR adaptor,pANTLR3_BASE_RECOGNIZER rec,pANTLR3_UINT8 description)442*16467b97STreehugger Robot antlr3RewriteRuleNODEStreamNewAE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description)
443*16467b97STreehugger Robot {
444*16467b97STreehugger Robot 	pANTLR3_REWRITE_RULE_NODE_STREAM	stream;
445*16467b97STreehugger Robot 
446*16467b97STreehugger Robot 	// First job is to create the memory we need.
447*16467b97STreehugger Robot 	//
448*16467b97STreehugger Robot 	stream	= antlr3RewriteRuleElementStreamNewAE(adaptor, rec, description);
449*16467b97STreehugger Robot 
450*16467b97STreehugger Robot 	if (stream == NULL)
451*16467b97STreehugger Robot 	{
452*16467b97STreehugger Robot 		return stream;
453*16467b97STreehugger Robot 	}
454*16467b97STreehugger Robot 
455*16467b97STreehugger Robot 	// Install the node based overrides
456*16467b97STreehugger Robot 	//
457*16467b97STreehugger Robot 	stream->dup			= dupTreeNode;
458*16467b97STreehugger Robot 	stream->toTree		= toTreeNode;
459*16467b97STreehugger Robot 	stream->nextNode	= nextNodeNode;
460*16467b97STreehugger Robot     stream->free        = freeNodeRS;
461*16467b97STreehugger Robot 
462*16467b97STreehugger Robot 	return stream;
463*16467b97STreehugger Robot }
464*16467b97STreehugger Robot 
465*16467b97STreehugger Robot ANTLR3_API pANTLR3_REWRITE_RULE_NODE_STREAM
antlr3RewriteRuleNODEStreamNewAEE(pANTLR3_BASE_TREE_ADAPTOR adaptor,pANTLR3_BASE_RECOGNIZER rec,pANTLR3_UINT8 description,void * oneElement)466*16467b97STreehugger Robot antlr3RewriteRuleNODEStreamNewAEE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description, void * oneElement)
467*16467b97STreehugger Robot {
468*16467b97STreehugger Robot 	pANTLR3_REWRITE_RULE_NODE_STREAM	stream;
469*16467b97STreehugger Robot 
470*16467b97STreehugger Robot 	// First job is to create the memory we need.
471*16467b97STreehugger Robot 	//
472*16467b97STreehugger Robot 	stream	= antlr3RewriteRuleElementStreamNewAEE(adaptor, rec, description, oneElement);
473*16467b97STreehugger Robot 
474*16467b97STreehugger Robot 	// Install the node based overrides
475*16467b97STreehugger Robot 	//
476*16467b97STreehugger Robot 	stream->dup			= dupTreeNode;
477*16467b97STreehugger Robot 	stream->toTree		= toTreeNode;
478*16467b97STreehugger Robot 	stream->nextNode	= nextNodeNode;
479*16467b97STreehugger Robot     stream->free        = freeNodeRS;
480*16467b97STreehugger Robot 
481*16467b97STreehugger Robot 	return stream;
482*16467b97STreehugger Robot }
483*16467b97STreehugger Robot 
484*16467b97STreehugger Robot ANTLR3_API pANTLR3_REWRITE_RULE_NODE_STREAM
antlr3RewriteRuleNODEStreamNewAEV(pANTLR3_BASE_TREE_ADAPTOR adaptor,pANTLR3_BASE_RECOGNIZER rec,pANTLR3_UINT8 description,pANTLR3_VECTOR vector)485*16467b97STreehugger Robot antlr3RewriteRuleNODEStreamNewAEV(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description, pANTLR3_VECTOR vector)
486*16467b97STreehugger Robot {
487*16467b97STreehugger Robot 	pANTLR3_REWRITE_RULE_NODE_STREAM	stream;
488*16467b97STreehugger Robot 
489*16467b97STreehugger Robot 	// First job is to create the memory we need.
490*16467b97STreehugger Robot 	//
491*16467b97STreehugger Robot 	stream	= antlr3RewriteRuleElementStreamNewAEV(adaptor, rec, description, vector);
492*16467b97STreehugger Robot 
493*16467b97STreehugger Robot 	// Install the Node based overrides
494*16467b97STreehugger Robot 	//
495*16467b97STreehugger Robot 	stream->dup			= dupTreeNode;
496*16467b97STreehugger Robot 	stream->toTree		= toTreeNode;
497*16467b97STreehugger Robot 	stream->nextNode	= nextNodeNode;
498*16467b97STreehugger Robot     stream->free        = freeNodeRS;
499*16467b97STreehugger Robot 
500*16467b97STreehugger Robot 	return stream;
501*16467b97STreehugger Robot }
502*16467b97STreehugger Robot 
503*16467b97STreehugger Robot //----------------------------------------------------------------------
504*16467b97STreehugger Robot // Static support functions
505*16467b97STreehugger Robot 
506*16467b97STreehugger Robot /// Reset the condition of this stream so that it appears we have
507*16467b97STreehugger Robot /// not consumed any of its elements.  Elements themselves are untouched.
508*16467b97STreehugger Robot ///
509*16467b97STreehugger Robot static void
reset(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)510*16467b97STreehugger Robot reset    (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)
511*16467b97STreehugger Robot {
512*16467b97STreehugger Robot 	stream->dirty	= ANTLR3_TRUE;
513*16467b97STreehugger Robot 	stream->cursor	= 0;
514*16467b97STreehugger Robot }
515*16467b97STreehugger Robot 
516*16467b97STreehugger Robot // Add a new pANTLR3_BASE_TREE to this stream
517*16467b97STreehugger Robot //
518*16467b97STreehugger Robot static void
add(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream,void * el,void (ANTLR3_CDECL * freePtr)(void *))519*16467b97STreehugger Robot add	    (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * el, void (ANTLR3_CDECL *freePtr)(void *))
520*16467b97STreehugger Robot {
521*16467b97STreehugger Robot 	if (el== NULL)
522*16467b97STreehugger Robot 	{
523*16467b97STreehugger Robot 		return;
524*16467b97STreehugger Robot 	}
525*16467b97STreehugger Robot 	// As we may be reusing a stream, we may already have allocated
526*16467b97STreehugger Robot 	// a rewrite stream vector. If we have then is will be empty if
527*16467b97STreehugger Robot 	// we have either zero or just one element in the rewrite stream
528*16467b97STreehugger Robot 	//
529*16467b97STreehugger Robot 	if (stream->elements != NULL && stream->elements->count > 0)
530*16467b97STreehugger Robot 	{
531*16467b97STreehugger Robot 		// We already have >1 entries in the stream. So we can just add this new element to the existing
532*16467b97STreehugger Robot 		// collection.
533*16467b97STreehugger Robot 		//
534*16467b97STreehugger Robot 		stream->elements->add(stream->elements, el, freePtr);
535*16467b97STreehugger Robot 		return;
536*16467b97STreehugger Robot 	}
537*16467b97STreehugger Robot 	if (stream->singleElement == NULL)
538*16467b97STreehugger Robot 	{
539*16467b97STreehugger Robot 		stream->singleElement = el;
540*16467b97STreehugger Robot 		return;
541*16467b97STreehugger Robot 	}
542*16467b97STreehugger Robot 
543*16467b97STreehugger Robot 	// If we got here then we had only the one element so far
544*16467b97STreehugger Robot 	// and we must now create a vector to hold a collection of them
545*16467b97STreehugger Robot 	//
546*16467b97STreehugger Robot 	if	(stream->elements == NULL)
547*16467b97STreehugger Robot 	{
548*16467b97STreehugger Robot         pANTLR3_VECTOR_FACTORY factory = ((pANTLR3_COMMON_TREE_ADAPTOR)(stream->adaptor->super))->arboretum->vFactory;
549*16467b97STreehugger Robot 
550*16467b97STreehugger Robot 
551*16467b97STreehugger Robot 		stream->elements		= factory->newVector(factory);
552*16467b97STreehugger Robot 		stream->freeElements	= ANTLR3_TRUE;			// We 'ummed it, so we play it son.
553*16467b97STreehugger Robot 	}
554*16467b97STreehugger Robot 
555*16467b97STreehugger Robot 	stream->elements->add	(stream->elements, stream->singleElement, freePtr);
556*16467b97STreehugger Robot 	stream->elements->add	(stream->elements, el, freePtr);
557*16467b97STreehugger Robot 	stream->singleElement	= NULL;
558*16467b97STreehugger Robot 
559*16467b97STreehugger Robot 	return;
560*16467b97STreehugger Robot }
561*16467b97STreehugger Robot 
562*16467b97STreehugger Robot /// Return the next element in the stream.  If out of elements, throw
563*16467b97STreehugger Robot /// an exception unless size()==1.  If size is 1, then return elements[0].
564*16467b97STreehugger Robot /// Return a duplicate node/subtree if stream is out of elements and
565*16467b97STreehugger Robot /// size==1.  If we've already used the element, dup (dirty bit set).
566*16467b97STreehugger Robot ///
567*16467b97STreehugger Robot static pANTLR3_BASE_TREE
nextTree(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)568*16467b97STreehugger Robot nextTree(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)
569*16467b97STreehugger Robot {
570*16467b97STreehugger Robot 	ANTLR3_UINT32		n;
571*16467b97STreehugger Robot 	void			*  el;
572*16467b97STreehugger Robot 
573*16467b97STreehugger Robot 	n = stream->size(stream);
574*16467b97STreehugger Robot 
575*16467b97STreehugger Robot 	if ( stream->dirty || (stream->cursor >=n && n==1) )
576*16467b97STreehugger Robot 	{
577*16467b97STreehugger Robot 		// if out of elements and size is 1, dup
578*16467b97STreehugger Robot 		//
579*16467b97STreehugger Robot 		el = stream->_next(stream);
580*16467b97STreehugger Robot 		return (pANTLR3_BASE_TREE)stream->dup(stream, el);
581*16467b97STreehugger Robot 	}
582*16467b97STreehugger Robot 
583*16467b97STreehugger Robot 	// test size above then fetch
584*16467b97STreehugger Robot 	//
585*16467b97STreehugger Robot 	el = stream->_next(stream);
586*16467b97STreehugger Robot 	return (pANTLR3_BASE_TREE)el;
587*16467b97STreehugger Robot }
588*16467b97STreehugger Robot 
589*16467b97STreehugger Robot /// Return the next element for a caller that wants just the token
590*16467b97STreehugger Robot ///
591*16467b97STreehugger Robot static	void *
nextToken(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)592*16467b97STreehugger Robot nextToken		(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)
593*16467b97STreehugger Robot {
594*16467b97STreehugger Robot 	return stream->_next(stream);
595*16467b97STreehugger Robot }
596*16467b97STreehugger Robot 
597*16467b97STreehugger Robot /// Return the next element in the stream.  If out of elements, throw
598*16467b97STreehugger Robot /// an exception unless size()==1.  If size is 1, then return elements[0].
599*16467b97STreehugger Robot ///
600*16467b97STreehugger Robot static void *
next(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)601*16467b97STreehugger Robot next	    (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)
602*16467b97STreehugger Robot {
603*16467b97STreehugger Robot 	ANTLR3_UINT32   s;
604*16467b97STreehugger Robot 
605*16467b97STreehugger Robot 	s = stream->size(stream);
606*16467b97STreehugger Robot 	if (stream->cursor >= s && s == 1)
607*16467b97STreehugger Robot 	{
608*16467b97STreehugger Robot 		pANTLR3_BASE_TREE el;
609*16467b97STreehugger Robot 
610*16467b97STreehugger Robot 		el = (pANTLR3_BASE_TREE)stream->_next(stream);
611*16467b97STreehugger Robot 
612*16467b97STreehugger Robot 		return	stream->dup(stream, el);
613*16467b97STreehugger Robot 	}
614*16467b97STreehugger Robot 
615*16467b97STreehugger Robot 	return stream->_next(stream);
616*16467b97STreehugger Robot }
617*16467b97STreehugger Robot 
618*16467b97STreehugger Robot /// Do the work of getting the next element, making sure that it's
619*16467b97STreehugger Robot /// a tree node or subtree.  Deal with the optimization of single-
620*16467b97STreehugger Robot /// element list versus list of size > 1.  Throw an exception (or something similar)
621*16467b97STreehugger Robot /// if the stream is empty or we're out of elements and size>1.
622*16467b97STreehugger Robot /// You can override in a 'subclass' if necessary.
623*16467b97STreehugger Robot ///
624*16467b97STreehugger Robot static void *
_next(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)625*16467b97STreehugger Robot _next    (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)
626*16467b97STreehugger Robot {
627*16467b97STreehugger Robot 	ANTLR3_UINT32		n;
628*16467b97STreehugger Robot 	pANTLR3_BASE_TREE	t;
629*16467b97STreehugger Robot 
630*16467b97STreehugger Robot 	n = stream->size(stream);
631*16467b97STreehugger Robot 
632*16467b97STreehugger Robot 	if (n == 0)
633*16467b97STreehugger Robot 	{
634*16467b97STreehugger Robot 		// This means that the stream is empty
635*16467b97STreehugger Robot 		//
636*16467b97STreehugger Robot 		return NULL;	// Caller must cope with this
637*16467b97STreehugger Robot 	}
638*16467b97STreehugger Robot 
639*16467b97STreehugger Robot 	// Traversed all the available elements already?
640*16467b97STreehugger Robot 	//
641*16467b97STreehugger Robot 	if (stream->cursor >= n)
642*16467b97STreehugger Robot 	{
643*16467b97STreehugger Robot 		if (n == 1)
644*16467b97STreehugger Robot 		{
645*16467b97STreehugger Robot 			// Special case when size is single element, it will just dup a lot
646*16467b97STreehugger Robot 			//
647*16467b97STreehugger Robot 			return stream->toTree(stream, stream->singleElement);
648*16467b97STreehugger Robot 		}
649*16467b97STreehugger Robot 
650*16467b97STreehugger Robot 		// Out of elements and the size is not 1, so we cannot assume
651*16467b97STreehugger Robot 		// that we just duplicate the entry n times (such as ID ent+ -> ^(ID ent)+)
652*16467b97STreehugger Robot 		// This means we ran out of elements earlier than was expected.
653*16467b97STreehugger Robot 		//
654*16467b97STreehugger Robot 		return NULL;	// Caller must cope with this
655*16467b97STreehugger Robot 	}
656*16467b97STreehugger Robot 
657*16467b97STreehugger Robot 	// Elements available either for duping or just available
658*16467b97STreehugger Robot 	//
659*16467b97STreehugger Robot 	if (stream->singleElement != NULL)
660*16467b97STreehugger Robot 	{
661*16467b97STreehugger Robot 		stream->cursor++;   // Cursor advances even for single element as this tells us to dup()
662*16467b97STreehugger Robot 		return stream->toTree(stream, stream->singleElement);
663*16467b97STreehugger Robot 	}
664*16467b97STreehugger Robot 
665*16467b97STreehugger Robot 	// More than just a single element so we extract it from the
666*16467b97STreehugger Robot 	// vector.
667*16467b97STreehugger Robot 	//
668*16467b97STreehugger Robot 	t = stream->toTree(stream, stream->elements->get(stream->elements, stream->cursor));
669*16467b97STreehugger Robot 	stream->cursor++;
670*16467b97STreehugger Robot 	return t;
671*16467b97STreehugger Robot }
672*16467b97STreehugger Robot 
673*16467b97STreehugger Robot #ifdef ANTLR3_WINDOWS
674*16467b97STreehugger Robot #pragma warning(push)
675*16467b97STreehugger Robot #pragma warning(disable : 4100)
676*16467b97STreehugger Robot #endif
677*16467b97STreehugger Robot /// When constructing trees, sometimes we need to dup a token or AST
678*16467b97STreehugger Robot /// subtree.  Dup'ing a token means just creating another AST node
679*16467b97STreehugger Robot /// around it.  For trees, you must call the adaptor.dupTree().
680*16467b97STreehugger Robot ///
681*16467b97STreehugger Robot static void *
dupTok(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream,void * el)682*16467b97STreehugger Robot dupTok	    (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * el)
683*16467b97STreehugger Robot {
684*16467b97STreehugger Robot 	ANTLR3_FPRINTF(stderr, "dup() cannot be called on a token rewrite stream!!");
685*16467b97STreehugger Robot 	return NULL;
686*16467b97STreehugger Robot }
687*16467b97STreehugger Robot #ifdef ANTLR3_WINDOWS
688*16467b97STreehugger Robot #pragma warning(pop)
689*16467b97STreehugger Robot #endif
690*16467b97STreehugger Robot 
691*16467b97STreehugger Robot /// When constructing trees, sometimes we need to dup a token or AST
692*16467b97STreehugger Robot /// subtree.  Dup'ing a token means just creating another AST node
693*16467b97STreehugger Robot /// around it.  For trees, you must call the adaptor.dupTree().
694*16467b97STreehugger Robot ///
695*16467b97STreehugger Robot static void *
dupTree(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream,void * element)696*16467b97STreehugger Robot dupTree	    (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * element)
697*16467b97STreehugger Robot {
698*16467b97STreehugger Robot 	return stream->adaptor->dupNode(stream->adaptor, (pANTLR3_BASE_TREE)element);
699*16467b97STreehugger Robot }
700*16467b97STreehugger Robot 
701*16467b97STreehugger Robot #ifdef ANTLR3_WINDOWS
702*16467b97STreehugger Robot #pragma warning(push)
703*16467b97STreehugger Robot #pragma warning(disable : 4100)
704*16467b97STreehugger Robot #endif
705*16467b97STreehugger Robot /// When constructing trees, sometimes we need to dup a token or AST
706*16467b97STreehugger Robot /// subtree.  Dup'ing a token means just creating another AST node
707*16467b97STreehugger Robot /// around it.  For trees, you must call the adaptor.dupTree().
708*16467b97STreehugger Robot ///
709*16467b97STreehugger Robot static void *
dupTreeNode(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream,void * element)710*16467b97STreehugger Robot dupTreeNode	    (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * element)
711*16467b97STreehugger Robot {
712*16467b97STreehugger Robot 	ANTLR3_FPRINTF(stderr, "dup() cannot be called on a node rewrite stream!!!");
713*16467b97STreehugger Robot 	return NULL;
714*16467b97STreehugger Robot }
715*16467b97STreehugger Robot 
716*16467b97STreehugger Robot 
717*16467b97STreehugger Robot /// We don;t explicitly convert to a tree unless the call goes to
718*16467b97STreehugger Robot /// nextTree, which means rewrites are heterogeneous
719*16467b97STreehugger Robot ///
720*16467b97STreehugger Robot static pANTLR3_BASE_TREE
toTree(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream,void * element)721*16467b97STreehugger Robot toTree   (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * element)
722*16467b97STreehugger Robot {
723*16467b97STreehugger Robot 	return (pANTLR3_BASE_TREE)element;
724*16467b97STreehugger Robot }
725*16467b97STreehugger Robot #ifdef ANTLR3_WINDOWS
726*16467b97STreehugger Robot #pragma warning(pop)
727*16467b97STreehugger Robot #endif
728*16467b97STreehugger Robot 
729*16467b97STreehugger Robot /// Ensure stream emits trees; tokens must be converted to AST nodes.
730*16467b97STreehugger Robot /// AST nodes can be passed through unmolested.
731*16467b97STreehugger Robot ///
732*16467b97STreehugger Robot #ifdef ANTLR3_WINDOWS
733*16467b97STreehugger Robot #pragma warning(push)
734*16467b97STreehugger Robot #pragma warning(disable : 4100)
735*16467b97STreehugger Robot #endif
736*16467b97STreehugger Robot 
737*16467b97STreehugger Robot static pANTLR3_BASE_TREE
toTreeNode(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream,void * element)738*16467b97STreehugger Robot toTreeNode   (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * element)
739*16467b97STreehugger Robot {
740*16467b97STreehugger Robot 	return (pANTLR3_BASE_TREE)stream->adaptor->dupNode(stream->adaptor, (pANTLR3_BASE_TREE)element);
741*16467b97STreehugger Robot }
742*16467b97STreehugger Robot 
743*16467b97STreehugger Robot #ifdef ANTLR3_WINDOWS
744*16467b97STreehugger Robot #pragma warning(pop)
745*16467b97STreehugger Robot #endif
746*16467b97STreehugger Robot 
747*16467b97STreehugger Robot /// Returns ANTLR3_TRUE if there is a next element available
748*16467b97STreehugger Robot ///
749*16467b97STreehugger Robot static ANTLR3_BOOLEAN
hasNext(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)750*16467b97STreehugger Robot hasNext  (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)
751*16467b97STreehugger Robot {
752*16467b97STreehugger Robot 	if (	(stream->singleElement != NULL && stream->cursor < 1)
753*16467b97STreehugger Robot 		||	(stream->elements != NULL && stream->cursor < stream->elements->size(stream->elements)))
754*16467b97STreehugger Robot 	{
755*16467b97STreehugger Robot 		return ANTLR3_TRUE;
756*16467b97STreehugger Robot 	}
757*16467b97STreehugger Robot 	else
758*16467b97STreehugger Robot 	{
759*16467b97STreehugger Robot 		return ANTLR3_FALSE;
760*16467b97STreehugger Robot 	}
761*16467b97STreehugger Robot }
762*16467b97STreehugger Robot 
763*16467b97STreehugger Robot /// Get the next token from the list and create a node for it
764*16467b97STreehugger Robot /// This is the implementation for token streams.
765*16467b97STreehugger Robot ///
766*16467b97STreehugger Robot static pANTLR3_BASE_TREE
nextNodeToken(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)767*16467b97STreehugger Robot nextNodeToken(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)
768*16467b97STreehugger Robot {
769*16467b97STreehugger Robot 	return (pANTLR3_BASE_TREE)stream->adaptor->create(stream->adaptor, (pANTLR3_COMMON_TOKEN)stream->_next(stream));
770*16467b97STreehugger Robot }
771*16467b97STreehugger Robot 
772*16467b97STreehugger Robot static pANTLR3_BASE_TREE
nextNodeNode(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)773*16467b97STreehugger Robot nextNodeNode(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)
774*16467b97STreehugger Robot {
775*16467b97STreehugger Robot 	return (pANTLR3_BASE_TREE)stream->_next(stream);
776*16467b97STreehugger Robot }
777*16467b97STreehugger Robot 
778*16467b97STreehugger Robot /// Treat next element as a single node even if it's a subtree.
779*16467b97STreehugger Robot /// This is used instead of next() when the result has to be a
780*16467b97STreehugger Robot /// tree root node.  Also prevents us from duplicating recently-added
781*16467b97STreehugger Robot /// children; e.g., ^(type ID)+ adds ID to type and then 2nd iteration
782*16467b97STreehugger Robot /// must dup the type node, but ID has been added.
783*16467b97STreehugger Robot ///
784*16467b97STreehugger Robot /// Referencing to a rule result twice is ok; dup entire tree as
785*16467b97STreehugger Robot /// we can't be adding trees; e.g., expr expr.
786*16467b97STreehugger Robot ///
787*16467b97STreehugger Robot static pANTLR3_BASE_TREE
nextNode(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)788*16467b97STreehugger Robot nextNode (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)
789*16467b97STreehugger Robot {
790*16467b97STreehugger Robot 
791*16467b97STreehugger Robot 	ANTLR3_UINT32	n;
792*16467b97STreehugger Robot 	pANTLR3_BASE_TREE	el = (pANTLR3_BASE_TREE)stream->_next(stream);
793*16467b97STreehugger Robot 
794*16467b97STreehugger Robot 	n = stream->size(stream);
795*16467b97STreehugger Robot 	if (stream->dirty == ANTLR3_TRUE || (stream->cursor > n && n == 1))
796*16467b97STreehugger Robot 	{
797*16467b97STreehugger Robot 		// We are out of elements and the size is 1, which means we just
798*16467b97STreehugger Robot 		// dup the node that we have
799*16467b97STreehugger Robot 		//
800*16467b97STreehugger Robot 		return	(pANTLR3_BASE_TREE)stream->adaptor->dupNode(stream->adaptor, el);
801*16467b97STreehugger Robot 	}
802*16467b97STreehugger Robot 
803*16467b97STreehugger Robot 	// We were not out of nodes, so the one we received is the one to return
804*16467b97STreehugger Robot 	//
805*16467b97STreehugger Robot 	return  el;
806*16467b97STreehugger Robot }
807*16467b97STreehugger Robot 
808*16467b97STreehugger Robot /// Number of elements available in the stream
809*16467b97STreehugger Robot ///
810*16467b97STreehugger Robot static ANTLR3_UINT32
size(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)811*16467b97STreehugger Robot size	    (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)
812*16467b97STreehugger Robot {
813*16467b97STreehugger Robot 	ANTLR3_UINT32   n = 0;
814*16467b97STreehugger Robot 
815*16467b97STreehugger Robot 	/// Should be a count of one if singleElement is set. I copied this
816*16467b97STreehugger Robot 	/// logic from the java implementation, which I suspect is just guarding
817*16467b97STreehugger Robot 	/// against someone setting singleElement and forgetting to NULL it out
818*16467b97STreehugger Robot 	///
819*16467b97STreehugger Robot 	if (stream->singleElement != NULL)
820*16467b97STreehugger Robot 	{
821*16467b97STreehugger Robot 		n = 1;
822*16467b97STreehugger Robot 	}
823*16467b97STreehugger Robot 	else
824*16467b97STreehugger Robot 	{
825*16467b97STreehugger Robot 		if (stream->elements != NULL)
826*16467b97STreehugger Robot 		{
827*16467b97STreehugger Robot 			return (ANTLR3_UINT32)(stream->elements->count);
828*16467b97STreehugger Robot 		}
829*16467b97STreehugger Robot 	}
830*16467b97STreehugger Robot 	return n;
831*16467b97STreehugger Robot }
832*16467b97STreehugger Robot 
833*16467b97STreehugger Robot /// Returns the description string if there is one available (check for NULL).
834*16467b97STreehugger Robot ///
835*16467b97STreehugger Robot static void *
getDescription(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)836*16467b97STreehugger Robot getDescription  (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)
837*16467b97STreehugger Robot {
838*16467b97STreehugger Robot 	if (stream->elementDescription == NULL)
839*16467b97STreehugger Robot 	{
840*16467b97STreehugger Robot 		stream->elementDescription = (void*)"<unknown source>";
841*16467b97STreehugger Robot 	}
842*16467b97STreehugger Robot 
843*16467b97STreehugger Robot 	return  stream->elementDescription;
844*16467b97STreehugger Robot }
845