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