2 /// Implementation of token/tree streams that are used by the
\r
3 /// tree re-write rules to manipulate the tokens and trees produced
\r
4 /// by rules that are subject to rewrite directives.
\r
7 // [The "BSD licence"]
\r
8 // Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC
\r
9 // http://www.temporal-wave.com
\r
10 // http://www.linkedin.com/in/jimidle
\r
12 // All rights reserved.
\r
14 // Redistribution and use in source and binary forms, with or without
\r
15 // modification, are permitted provided that the following conditions
\r
17 // 1. Redistributions of source code must retain the above copyright
\r
18 // notice, this list of conditions and the following disclaimer.
\r
19 // 2. Redistributions in binary form must reproduce the above copyright
\r
20 // notice, this list of conditions and the following disclaimer in the
\r
21 // documentation and/or other materials provided with the distribution.
\r
22 // 3. The name of the author may not be used to endorse or promote products
\r
23 // derived from this software without specific prior written permission.
\r
25 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
\r
26 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
\r
27 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
\r
28 // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
\r
29 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
\r
30 // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
\r
31 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
\r
32 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
\r
33 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
\r
34 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
36 #include <antlr3rewritestreams.h>
\r
38 // Static support function forward declarations for the stream types.
\r
40 static void reset (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);
\r
41 static void add (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * el, void (ANTLR3_CDECL *freePtr)(void *));
\r
42 static void * next (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);
\r
43 static pANTLR3_BASE_TREE nextTree (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);
\r
44 static void * nextToken (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);
\r
45 static void * _next (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);
\r
46 static void * dupTok (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * el);
\r
47 static void * dupTree (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * el);
\r
48 static void * dupTreeNode (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * el);
\r
49 static pANTLR3_BASE_TREE toTree (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * element);
\r
50 static pANTLR3_BASE_TREE toTreeNode (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * element);
\r
51 static ANTLR3_BOOLEAN hasNext (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);
\r
52 static pANTLR3_BASE_TREE nextNode (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);
\r
53 static pANTLR3_BASE_TREE nextNodeNode (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);
\r
54 static pANTLR3_BASE_TREE nextNodeToken (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);
\r
55 static ANTLR3_UINT32 size (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);
\r
56 static void * getDescription (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);
\r
57 static void freeRS (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);
\r
58 static void expungeRS (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream);
\r
61 // Place a now unused rewrite stream back on the rewrite stream pool
\r
62 // so we can reuse it if we need to.
\r
65 freeRS (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)
\r
67 // Before placing the stream back in the pool, we
\r
68 // need to clear any vector it has. This is so any
\r
69 // free pointers that are associated with the
\r
70 // entires are called.
\r
72 if (stream->elements != NULL)
\r
74 // Factory generated vectors can be returned to the
\r
75 // vector factory for later reuse.
\r
77 if (stream->elements->factoryMade == ANTLR3_TRUE)
\r
79 pANTLR3_VECTOR_FACTORY factory = ((pANTLR3_COMMON_TREE_ADAPTOR)(stream->adaptor->super))->arboretum->vFactory;
\r
80 factory->returnVector(factory, stream->elements);
\r
82 stream->elements = NULL;
\r
86 // Other vectors we clear and allow to be reused if they come off the
\r
87 // rewrite stream free stack and are reused.
\r
89 stream->elements->clear(stream->elements);
\r
90 stream->freeElements = ANTLR3_TRUE;
\r
95 stream->freeElements = ANTLR3_FALSE; // Just in case
\r
98 // Add the stream into the recognizer stream stack vector
\r
99 // adding the stream memory free routine so that
\r
100 // it is thrown away when the stack vector is destroyed
\r
102 stream->rec->state->rStreams->add(stream->rec->state->rStreams, stream, (void(*)(void *))expungeRS);
\r
105 /** Do special nilNode reuse detection for node streams.
\r
108 freeNodeRS(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)
\r
110 pANTLR3_BASE_TREE tree;
\r
112 // Before placing the stream back in the pool, we
\r
113 // need to clear any vector it has. This is so any
\r
114 // free pointers that are associated with the
\r
115 // entires are called. However, if this particular function is called
\r
116 // then we know that the entries in the stream are definately
\r
117 // tree nodes. Hence we check to see if any of them were nilNodes as
\r
118 // if they were, we can reuse them.
\r
120 if (stream->elements != NULL)
\r
122 // We have some elements to traverse
\r
126 for (i = 1; i<= stream->elements->count; i++)
\r
128 tree = (pANTLR3_BASE_TREE)(stream->elements->elements[i-1].element);
\r
129 if (tree != NULL && tree->isNilNode(tree))
\r
131 // Had to remove this for now, check is not comprehensive enough
\r
132 // tree->reuse(tree);
\r
136 // Factory generated vectors can be returned to the
\r
137 // vector factory for later reuse.
\r
139 if (stream->elements->factoryMade == ANTLR3_TRUE)
\r
141 pANTLR3_VECTOR_FACTORY factory = ((pANTLR3_COMMON_TREE_ADAPTOR)(stream->adaptor->super))->arboretum->vFactory;
\r
142 factory->returnVector(factory, stream->elements);
\r
144 stream->elements = NULL;
\r
148 stream->elements->clear(stream->elements);
\r
149 stream->freeElements = ANTLR3_TRUE;
\r
154 if (stream->singleElement != NULL)
\r
156 tree = (pANTLR3_BASE_TREE)(stream->singleElement);
\r
157 if (tree->isNilNode(tree))
\r
159 // Had to remove this for now, check is not comprehensive enough
\r
160 // tree->reuse(tree);
\r
163 stream->singleElement = NULL;
\r
164 stream->freeElements = ANTLR3_FALSE; // Just in case
\r
167 // Add the stream into the recognizer stream stack vector
\r
168 // adding the stream memory free routine so that
\r
169 // it is thrown away when the stack vector is destroyed
\r
171 stream->rec->state->rStreams->add(stream->rec->state->rStreams, stream, (void(*)(void *))expungeRS);
\r
174 expungeRS(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)
\r
177 if (stream->freeElements == ANTLR3_TRUE && stream->elements != NULL)
\r
179 stream->elements->free(stream->elements);
\r
181 ANTLR3_FREE(stream);
\r
184 // Functions for creating streams
\r
186 static pANTLR3_REWRITE_RULE_ELEMENT_STREAM
\r
187 antlr3RewriteRuleElementStreamNewAE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description)
\r
189 pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream;
\r
191 // First - do we already have a rewrite stream that was returned
\r
192 // to the pool? If we do, then we will just reuse it by resetting
\r
193 // the generic interface.
\r
195 if (rec->state->rStreams->count > 0)
\r
197 // Remove the entry from the vector. We do not
\r
198 // cause it to be freed by using remove.
\r
200 stream = rec->state->rStreams->remove(rec->state->rStreams, rec->state->rStreams->count - 1);
\r
202 // We found a stream we can reuse.
\r
203 // If the stream had a vector, then it will have been cleared
\r
204 // when the freeRS was called that put it in this stack
\r
209 // Ok, we need to allocate a new one as there were none on the stack.
\r
210 // First job is to create the memory we need.
\r
212 stream = (pANTLR3_REWRITE_RULE_ELEMENT_STREAM) ANTLR3_MALLOC((size_t)(sizeof(ANTLR3_REWRITE_RULE_ELEMENT_STREAM)));
\r
214 if (stream == NULL)
\r
218 stream->elements = NULL;
\r
219 stream->freeElements = ANTLR3_FALSE;
\r
222 // Populate the generic interface
\r
225 stream->reset = reset;
\r
227 stream->next = next;
\r
228 stream->nextTree = nextTree;
\r
229 stream->nextNode = nextNode;
\r
230 stream->nextToken = nextToken;
\r
231 stream->_next = _next;
\r
232 stream->hasNext = hasNext;
\r
233 stream->size = size;
\r
234 stream->getDescription = getDescription;
\r
235 stream->toTree = toTree;
\r
236 stream->free = freeRS;
\r
237 stream->singleElement = NULL;
\r
239 // Reset the stream to empty.
\r
242 stream->cursor = 0;
\r
243 stream->dirty = ANTLR3_FALSE;
\r
245 // Install the description
\r
247 stream->elementDescription = description;
\r
249 // Install the adaptor
\r
251 stream->adaptor = adaptor;
\r
256 static pANTLR3_REWRITE_RULE_ELEMENT_STREAM
\r
257 antlr3RewriteRuleElementStreamNewAEE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description, void * oneElement)
\r
259 pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream;
\r
261 // First job is to create the memory we need.
\r
263 stream = antlr3RewriteRuleElementStreamNewAE(adaptor, rec, description);
\r
265 if (stream == NULL)
\r
270 // Stream seems good so we need to add the supplied element
\r
272 if (oneElement != NULL)
\r
274 stream->add(stream, oneElement, NULL);
\r
279 static pANTLR3_REWRITE_RULE_ELEMENT_STREAM
\r
280 antlr3RewriteRuleElementStreamNewAEV(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description, pANTLR3_VECTOR vector)
\r
282 pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream;
\r
284 // First job is to create the memory we need.
\r
286 stream = antlr3RewriteRuleElementStreamNewAE(adaptor, rec, description);
\r
288 if (stream == NULL)
\r
293 // Stream seems good so we need to install the vector we were
\r
294 // given. We assume that someone else is going to free the
\r
297 if (stream->elements != NULL && stream->elements->factoryMade == ANTLR3_FALSE && stream->freeElements == ANTLR3_TRUE )
\r
299 stream->elements->free(stream->elements);
\r
301 stream->elements = vector;
\r
302 stream->freeElements = ANTLR3_FALSE;
\r
306 // Token rewrite stream ...
\r
308 ANTLR3_API pANTLR3_REWRITE_RULE_TOKEN_STREAM
\r
309 antlr3RewriteRuleTOKENStreamNewAE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description)
\r
311 pANTLR3_REWRITE_RULE_TOKEN_STREAM stream;
\r
313 // First job is to create the memory we need.
\r
315 stream = antlr3RewriteRuleElementStreamNewAE(adaptor, rec, description);
\r
317 if (stream == NULL)
\r
322 // Install the token based overrides
\r
324 stream->dup = dupTok;
\r
325 stream->nextNode = nextNodeToken;
\r
327 // No nextNode implementation for a token rewrite stream
\r
332 ANTLR3_API pANTLR3_REWRITE_RULE_TOKEN_STREAM
\r
333 antlr3RewriteRuleTOKENStreamNewAEE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description, void * oneElement)
\r
335 pANTLR3_REWRITE_RULE_TOKEN_STREAM stream;
\r
337 // First job is to create the memory we need.
\r
339 stream = antlr3RewriteRuleElementStreamNewAEE(adaptor, rec, description, oneElement);
\r
341 // Install the token based overrides
\r
343 stream->dup = dupTok;
\r
344 stream->nextNode = nextNodeToken;
\r
346 // No nextNode implementation for a token rewrite stream
\r
351 ANTLR3_API pANTLR3_REWRITE_RULE_TOKEN_STREAM
\r
352 antlr3RewriteRuleTOKENStreamNewAEV(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description, pANTLR3_VECTOR vector)
\r
354 pANTLR3_REWRITE_RULE_TOKEN_STREAM stream;
\r
356 // First job is to create the memory we need.
\r
358 stream = antlr3RewriteRuleElementStreamNewAEV(adaptor, rec, description, vector);
\r
360 // Install the token based overrides
\r
362 stream->dup = dupTok;
\r
363 stream->nextNode = nextNodeToken;
\r
365 // No nextNode implementation for a token rewrite stream
\r
370 // Subtree rewrite stream
\r
372 ANTLR3_API pANTLR3_REWRITE_RULE_SUBTREE_STREAM
\r
373 antlr3RewriteRuleSubtreeStreamNewAE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description)
\r
375 pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream;
\r
377 // First job is to create the memory we need.
\r
379 stream = antlr3RewriteRuleElementStreamNewAE(adaptor, rec, description);
\r
381 if (stream == NULL)
\r
386 // Install the subtree based overrides
\r
388 stream->dup = dupTree;
\r
389 stream->nextNode = nextNode;
\r
390 stream->free = freeNodeRS;
\r
394 ANTLR3_API pANTLR3_REWRITE_RULE_SUBTREE_STREAM
\r
395 antlr3RewriteRuleSubtreeStreamNewAEE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description, void * oneElement)
\r
397 pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream;
\r
399 // First job is to create the memory we need.
\r
401 stream = antlr3RewriteRuleElementStreamNewAEE(adaptor, rec, description, oneElement);
\r
403 if (stream == NULL)
\r
408 // Install the subtree based overrides
\r
410 stream->dup = dupTree;
\r
411 stream->nextNode = nextNode;
\r
412 stream->free = freeNodeRS;
\r
417 ANTLR3_API pANTLR3_REWRITE_RULE_SUBTREE_STREAM
\r
418 antlr3RewriteRuleSubtreeStreamNewAEV(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description, pANTLR3_VECTOR vector)
\r
420 pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream;
\r
422 // First job is to create the memory we need.
\r
424 stream = antlr3RewriteRuleElementStreamNewAEV(adaptor, rec, description, vector);
\r
426 if (stream == NULL)
\r
431 // Install the subtree based overrides
\r
433 stream->dup = dupTree;
\r
434 stream->nextNode = nextNode;
\r
435 stream->free = freeNodeRS;
\r
439 // Node rewrite stream ...
\r
441 ANTLR3_API pANTLR3_REWRITE_RULE_NODE_STREAM
\r
442 antlr3RewriteRuleNODEStreamNewAE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description)
\r
444 pANTLR3_REWRITE_RULE_NODE_STREAM stream;
\r
446 // First job is to create the memory we need.
\r
448 stream = antlr3RewriteRuleElementStreamNewAE(adaptor, rec, description);
\r
450 if (stream == NULL)
\r
455 // Install the node based overrides
\r
457 stream->dup = dupTreeNode;
\r
458 stream->toTree = toTreeNode;
\r
459 stream->nextNode = nextNodeNode;
\r
460 stream->free = freeNodeRS;
\r
465 ANTLR3_API pANTLR3_REWRITE_RULE_NODE_STREAM
\r
466 antlr3RewriteRuleNODEStreamNewAEE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description, void * oneElement)
\r
468 pANTLR3_REWRITE_RULE_NODE_STREAM stream;
\r
470 // First job is to create the memory we need.
\r
472 stream = antlr3RewriteRuleElementStreamNewAEE(adaptor, rec, description, oneElement);
\r
474 // Install the node based overrides
\r
476 stream->dup = dupTreeNode;
\r
477 stream->toTree = toTreeNode;
\r
478 stream->nextNode = nextNodeNode;
\r
479 stream->free = freeNodeRS;
\r
484 ANTLR3_API pANTLR3_REWRITE_RULE_NODE_STREAM
\r
485 antlr3RewriteRuleNODEStreamNewAEV(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description, pANTLR3_VECTOR vector)
\r
487 pANTLR3_REWRITE_RULE_NODE_STREAM stream;
\r
489 // First job is to create the memory we need.
\r
491 stream = antlr3RewriteRuleElementStreamNewAEV(adaptor, rec, description, vector);
\r
493 // Install the Node based overrides
\r
495 stream->dup = dupTreeNode;
\r
496 stream->toTree = toTreeNode;
\r
497 stream->nextNode = nextNodeNode;
\r
498 stream->free = freeNodeRS;
\r
503 //----------------------------------------------------------------------
\r
504 // Static support functions
\r
506 /// Reset the condition of this stream so that it appears we have
\r
507 /// not consumed any of its elements. Elements themselves are untouched.
\r
510 reset (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)
\r
512 stream->dirty = ANTLR3_TRUE;
\r
513 stream->cursor = 0;
\r
516 // Add a new pANTLR3_BASE_TREE to this stream
\r
519 add (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * el, void (ANTLR3_CDECL *freePtr)(void *))
\r
525 // As we may be reusing a stream, we may already have allocated
\r
526 // a rewrite stream vector. If we have then is will be empty if
\r
527 // we have either zero or just one element in the rewrite stream
\r
529 if (stream->elements != NULL && stream->elements->count > 0)
\r
531 // We already have >1 entries in the stream. So we can just add this new element to the existing
\r
534 stream->elements->add(stream->elements, el, freePtr);
\r
537 if (stream->singleElement == NULL)
\r
539 stream->singleElement = el;
\r
543 // If we got here then we had only the one element so far
\r
544 // and we must now create a vector to hold a collection of them
\r
546 if (stream->elements == NULL)
\r
548 pANTLR3_VECTOR_FACTORY factory = ((pANTLR3_COMMON_TREE_ADAPTOR)(stream->adaptor->super))->arboretum->vFactory;
\r
551 stream->elements = factory->newVector(factory);
\r
552 stream->freeElements = ANTLR3_TRUE; // We 'ummed it, so we play it son.
\r
555 stream->elements->add (stream->elements, stream->singleElement, freePtr);
\r
556 stream->elements->add (stream->elements, el, freePtr);
\r
557 stream->singleElement = NULL;
\r
562 /// Return the next element in the stream. If out of elements, throw
\r
563 /// an exception unless size()==1. If size is 1, then return elements[0].
\r
564 /// Return a duplicate node/subtree if stream is out of elements and
\r
565 /// size==1. If we've already used the element, dup (dirty bit set).
\r
567 static pANTLR3_BASE_TREE
\r
568 nextTree(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)
\r
573 n = stream->size(stream);
\r
575 if ( stream->dirty || (stream->cursor >=n && n==1) )
\r
577 // if out of elements and size is 1, dup
\r
579 el = stream->_next(stream);
\r
580 return stream->dup(stream, el);
\r
583 // test size above then fetch
\r
585 el = stream->_next(stream);
\r
589 /// Return the next element for a caller that wants just the token
\r
592 nextToken (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)
\r
594 return stream->_next(stream);
\r
597 /// Return the next element in the stream. If out of elements, throw
\r
598 /// an exception unless size()==1. If size is 1, then return elements[0].
\r
601 next (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)
\r
605 s = stream->size(stream);
\r
606 if (stream->cursor >= s && s == 1)
\r
608 pANTLR3_BASE_TREE el;
\r
610 el = stream->_next(stream);
\r
612 return stream->dup(stream, el);
\r
615 return stream->_next(stream);
\r
618 /// Do the work of getting the next element, making sure that it's
\r
619 /// a tree node or subtree. Deal with the optimization of single-
\r
620 /// element list versus list of size > 1. Throw an exception (or something similar)
\r
621 /// if the stream is empty or we're out of elements and size>1.
\r
622 /// You can override in a 'subclass' if necessary.
\r
625 _next (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)
\r
628 pANTLR3_BASE_TREE t;
\r
630 n = stream->size(stream);
\r
634 // This means that the stream is empty
\r
636 return NULL; // Caller must cope with this
\r
639 // Traversed all the available elements already?
\r
641 if (stream->cursor >= n)
\r
645 // Special case when size is single element, it will just dup a lot
\r
647 return stream->toTree(stream, stream->singleElement);
\r
650 // Out of elements and the size is not 1, so we cannot assume
\r
651 // that we just duplicate the entry n times (such as ID ent+ -> ^(ID ent)+)
\r
652 // This means we ran out of elements earlier than was expected.
\r
654 return NULL; // Caller must cope with this
\r
657 // Elements available either for duping or just available
\r
659 if (stream->singleElement != NULL)
\r
661 stream->cursor++; // Cursor advances even for single element as this tells us to dup()
\r
662 return stream->toTree(stream, stream->singleElement);
\r
665 // More than just a single element so we extract it from the
\r
668 t = stream->toTree(stream, stream->elements->get(stream->elements, stream->cursor));
\r
673 #ifdef ANTLR3_WINDOWS
\r
674 #pragma warning(push)
\r
675 #pragma warning(disable : 4100)
\r
677 /// When constructing trees, sometimes we need to dup a token or AST
\r
678 /// subtree. Dup'ing a token means just creating another AST node
\r
679 /// around it. For trees, you must call the adaptor.dupTree().
\r
682 dupTok (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * el)
\r
684 ANTLR3_FPRINTF(stderr, "dup() cannot be called on a token rewrite stream!!");
\r
687 #ifdef ANTLR3_WINDOWS
\r
688 #pragma warning(pop)
\r
691 /// When constructing trees, sometimes we need to dup a token or AST
\r
692 /// subtree. Dup'ing a token means just creating another AST node
\r
693 /// around it. For trees, you must call the adaptor.dupTree().
\r
696 dupTree (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * element)
\r
698 return stream->adaptor->dupNode(stream->adaptor, (pANTLR3_BASE_TREE)element);
\r
701 #ifdef ANTLR3_WINDOWS
\r
702 #pragma warning(push)
\r
703 #pragma warning(disable : 4100)
\r
705 /// When constructing trees, sometimes we need to dup a token or AST
\r
706 /// subtree. Dup'ing a token means just creating another AST node
\r
707 /// around it. For trees, you must call the adaptor.dupTree().
\r
710 dupTreeNode (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * element)
\r
712 ANTLR3_FPRINTF(stderr, "dup() cannot be called on a node rewrite stream!!!");
\r
717 /// We don;t explicitly convert to a tree unless the call goes to
\r
718 /// nextTree, which means rewrites are heterogeneous
\r
720 static pANTLR3_BASE_TREE
\r
721 toTree (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * element)
\r
723 return (pANTLR3_BASE_TREE)element;
\r
725 #ifdef ANTLR3_WINDOWS
\r
726 #pragma warning(pop)
\r
729 /// Ensure stream emits trees; tokens must be converted to AST nodes.
\r
730 /// AST nodes can be passed through unmolested.
\r
732 #ifdef ANTLR3_WINDOWS
\r
733 #pragma warning(push)
\r
734 #pragma warning(disable : 4100)
\r
737 static pANTLR3_BASE_TREE
\r
738 toTreeNode (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * element)
\r
740 return stream->adaptor->dupNode(stream->adaptor, (pANTLR3_BASE_TREE)element);
\r
743 #ifdef ANTLR3_WINDOWS
\r
744 #pragma warning(pop)
\r
747 /// Returns ANTLR3_TRUE if there is a next element available
\r
749 static ANTLR3_BOOLEAN
\r
750 hasNext (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)
\r
752 if ( (stream->singleElement != NULL && stream->cursor < 1)
\r
753 || (stream->elements != NULL && stream->cursor < stream->elements->size(stream->elements)))
\r
755 return ANTLR3_TRUE;
\r
759 return ANTLR3_FALSE;
\r
763 /// Get the next token from the list and create a node for it
\r
764 /// This is the implementation for token streams.
\r
766 static pANTLR3_BASE_TREE
\r
767 nextNodeToken(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)
\r
769 return stream->adaptor->create(stream->adaptor, stream->_next(stream));
\r
772 static pANTLR3_BASE_TREE
\r
773 nextNodeNode(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)
\r
775 return stream->_next(stream);
\r
778 /// Treat next element as a single node even if it's a subtree.
\r
779 /// This is used instead of next() when the result has to be a
\r
780 /// tree root node. Also prevents us from duplicating recently-added
\r
781 /// children; e.g., ^(type ID)+ adds ID to type and then 2nd iteration
\r
782 /// must dup the type node, but ID has been added.
\r
784 /// Referencing to a rule result twice is ok; dup entire tree as
\r
785 /// we can't be adding trees; e.g., expr expr.
\r
787 static pANTLR3_BASE_TREE
\r
788 nextNode (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)
\r
792 pANTLR3_BASE_TREE el = stream->_next(stream);
\r
794 n = stream->size(stream);
\r
795 if (stream->dirty == ANTLR3_TRUE || (stream->cursor > n && n == 1))
\r
797 // We are out of elements and the size is 1, which means we just
\r
798 // dup the node that we have
\r
800 return stream->adaptor->dupNode(stream->adaptor, el);
\r
803 // We were not out of nodes, so the one we received is the one to return
\r
808 /// Number of elements available in the stream
\r
810 static ANTLR3_UINT32
\r
811 size (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)
\r
813 ANTLR3_UINT32 n = 0;
\r
815 /// Should be a count of one if singleElement is set. I copied this
\r
816 /// logic from the java implementation, which I suspect is just guarding
\r
817 /// against someone setting singleElement and forgetting to NULL it out
\r
819 if (stream->singleElement != NULL)
\r
825 if (stream->elements != NULL)
\r
827 return (ANTLR3_UINT32)(stream->elements->count);
\r
833 /// Returns the description string if there is one available (check for NULL).
\r
836 getDescription (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)
\r
838 if (stream->elementDescription == NULL)
\r
840 stream->elementDescription = "<unknown source>";
\r
843 return stream->elementDescription;
\r