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.
8 // Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC
9 // http://www.temporal-wave.com
10 // http://www.linkedin.com/in/jimidle
12 // All rights reserved.
14 // Redistribution and use in source and binary forms, with or without
15 // modification, are permitted provided that the following conditions
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.
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.
36 #include <antlr3rewritestreams.h>
38 // Static support function forward declarations for the stream types.
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
);
61 // Place a now unused rewrite stream back on the rewrite stream pool
62 // so we can reuse it if we need to.
65 freeRS (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream
)
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.
72 if (stream
->elements
!= NULL
)
74 // Factory generated vectors can be returned to the
75 // vector factory for later reuse.
77 if (stream
->elements
->factoryMade
== ANTLR3_TRUE
)
79 pANTLR3_VECTOR_FACTORY factory
= ((pANTLR3_COMMON_TREE_ADAPTOR
)(stream
->adaptor
->super
))->arboretum
->vFactory
;
80 factory
->returnVector(factory
, stream
->elements
);
82 stream
->elements
= NULL
;
86 // Other vectors we clear and allow to be reused if they come off the
87 // rewrite stream free stack and are reused.
89 vectorClear(stream
->elements
);
90 stream
->freeElements
= ANTLR3_TRUE
;
95 stream
->freeElements
= ANTLR3_FALSE
; // Just in case
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
102 vectorAdd(stream
->rec
->state
->rStreams
, stream
, (void(*)(void *))expungeRS
);
105 /** Do special nilNode reuse detection for node streams.
108 freeNodeRS(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream
)
110 pANTLR3_BASE_TREE tree
;
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.
120 if (stream
->elements
!= NULL
)
122 // We have some elements to traverse
126 for (i
= 1; i
<= stream
->elements
->count
; i
++)
128 tree
= (pANTLR3_BASE_TREE
)(stream
->elements
->elements
[i
-1].element
);
129 if (tree
!= NULL
&& tree
->isNilNode(tree
))
131 // Had to remove this for now, check is not comprehensive enough
132 // tree->reuse(tree);
136 // Factory generated vectors can be returned to the
137 // vector factory for later reuse.
139 if (stream
->elements
->factoryMade
== ANTLR3_TRUE
)
141 pANTLR3_VECTOR_FACTORY factory
= ((pANTLR3_COMMON_TREE_ADAPTOR
)(stream
->adaptor
->super
))->arboretum
->vFactory
;
142 factory
->returnVector(factory
, stream
->elements
);
144 stream
->elements
= NULL
;
148 vectorClear(stream
->elements
);
149 stream
->freeElements
= ANTLR3_TRUE
;
154 if (stream
->singleElement
!= NULL
)
156 tree
= (pANTLR3_BASE_TREE
)(stream
->singleElement
);
157 if (tree
->isNilNode(tree
))
159 // Had to remove this for now, check is not comprehensive enough
160 // tree->reuse(tree);
163 stream
->singleElement
= NULL
;
164 stream
->freeElements
= ANTLR3_FALSE
; // Just in case
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
171 vectorAdd(stream
->rec
->state
->rStreams
, stream
, (void(*)(void *))expungeRS
);
174 expungeRS(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream
)
177 if (stream
->freeElements
== ANTLR3_TRUE
&& stream
->elements
!= NULL
)
179 vectorFree(stream
->elements
);
184 // Functions for creating streams
186 static pANTLR3_REWRITE_RULE_ELEMENT_STREAM
187 antlr3RewriteRuleElementStreamNewAE(pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_RECOGNIZER rec
, pANTLR3_UINT8 description
)
189 pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream
;
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.
195 if (rec
->state
->rStreams
->count
> 0)
197 // Remove the entry from the vector. We do not
198 // cause it to be freed by using remove.
200 stream
= vectorRemove(rec
->state
->rStreams
, rec
->state
->rStreams
->count
- 1);
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
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.
212 stream
= (pANTLR3_REWRITE_RULE_ELEMENT_STREAM
) ANTLR3_MALLOC((size_t)(sizeof(ANTLR3_REWRITE_RULE_ELEMENT_STREAM
)));
218 stream
->elements
= NULL
;
219 stream
->freeElements
= ANTLR3_FALSE
;
222 // Populate the generic interface
225 stream
->reset
= reset
;
228 stream
->nextTree
= nextTree
;
229 stream
->nextNode
= nextNode
;
230 stream
->nextToken
= nextToken
;
231 stream
->_next
= _next
;
232 stream
->hasNext
= hasNext
;
234 stream
->getDescription
= getDescription
;
235 stream
->toTree
= toTree
;
236 stream
->free
= freeRS
;
237 stream
->singleElement
= NULL
;
239 // Reset the stream to empty.
243 stream
->dirty
= ANTLR3_FALSE
;
245 // Install the description
247 stream
->elementDescription
= description
;
249 // Install the adaptor
251 stream
->adaptor
= adaptor
;
256 static pANTLR3_REWRITE_RULE_ELEMENT_STREAM
257 antlr3RewriteRuleElementStreamNewAEE(pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_RECOGNIZER rec
, pANTLR3_UINT8 description
, void * oneElement
)
259 pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream
;
261 // First job is to create the memory we need.
263 stream
= antlr3RewriteRuleElementStreamNewAE(adaptor
, rec
, description
);
270 // Stream seems good so we need to add the supplied element
272 if (oneElement
!= NULL
)
274 stream
->add(stream
, oneElement
, NULL
);
279 static pANTLR3_REWRITE_RULE_ELEMENT_STREAM
280 antlr3RewriteRuleElementStreamNewAEV(pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_RECOGNIZER rec
, pANTLR3_UINT8 description
, pANTLR3_VECTOR vector
)
282 pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream
;
284 // First job is to create the memory we need.
286 stream
= antlr3RewriteRuleElementStreamNewAE(adaptor
, rec
, description
);
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
297 if (stream
->elements
!= NULL
&& stream
->elements
->factoryMade
== ANTLR3_FALSE
&& stream
->freeElements
== ANTLR3_TRUE
)
299 vectorFree(stream
->elements
);
301 stream
->elements
= vector
;
302 stream
->freeElements
= ANTLR3_FALSE
;
306 // Token rewrite stream ...
308 ANTLR3_API pANTLR3_REWRITE_RULE_TOKEN_STREAM
309 antlr3RewriteRuleTOKENStreamNewAE(pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_RECOGNIZER rec
, pANTLR3_UINT8 description
)
311 pANTLR3_REWRITE_RULE_TOKEN_STREAM stream
;
313 // First job is to create the memory we need.
315 stream
= antlr3RewriteRuleElementStreamNewAE(adaptor
, rec
, description
);
322 // Install the token based overrides
324 stream
->dup
= dupTok
;
325 stream
->nextNode
= nextNodeToken
;
327 // No nextNode implementation for a token rewrite stream
332 ANTLR3_API pANTLR3_REWRITE_RULE_TOKEN_STREAM
333 antlr3RewriteRuleTOKENStreamNewAEE(pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_RECOGNIZER rec
, pANTLR3_UINT8 description
, void * oneElement
)
335 pANTLR3_REWRITE_RULE_TOKEN_STREAM stream
;
337 // First job is to create the memory we need.
339 stream
= antlr3RewriteRuleElementStreamNewAEE(adaptor
, rec
, description
, oneElement
);
341 // Install the token based overrides
343 stream
->dup
= dupTok
;
344 stream
->nextNode
= nextNodeToken
;
346 // No nextNode implementation for a token rewrite stream
351 ANTLR3_API pANTLR3_REWRITE_RULE_TOKEN_STREAM
352 antlr3RewriteRuleTOKENStreamNewAEV(pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_RECOGNIZER rec
, pANTLR3_UINT8 description
, pANTLR3_VECTOR vector
)
354 pANTLR3_REWRITE_RULE_TOKEN_STREAM stream
;
356 // First job is to create the memory we need.
358 stream
= antlr3RewriteRuleElementStreamNewAEV(adaptor
, rec
, description
, vector
);
360 // Install the token based overrides
362 stream
->dup
= dupTok
;
363 stream
->nextNode
= nextNodeToken
;
365 // No nextNode implementation for a token rewrite stream
370 // Subtree rewrite stream
372 ANTLR3_API pANTLR3_REWRITE_RULE_SUBTREE_STREAM
373 antlr3RewriteRuleSubtreeStreamNewAE(pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_RECOGNIZER rec
, pANTLR3_UINT8 description
)
375 pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream
;
377 // First job is to create the memory we need.
379 stream
= antlr3RewriteRuleElementStreamNewAE(adaptor
, rec
, description
);
386 // Install the subtree based overrides
388 stream
->dup
= dupTree
;
389 stream
->nextNode
= nextNode
;
390 stream
->free
= freeNodeRS
;
394 ANTLR3_API pANTLR3_REWRITE_RULE_SUBTREE_STREAM
395 antlr3RewriteRuleSubtreeStreamNewAEE(pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_RECOGNIZER rec
, pANTLR3_UINT8 description
, void * oneElement
)
397 pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream
;
399 // First job is to create the memory we need.
401 stream
= antlr3RewriteRuleElementStreamNewAEE(adaptor
, rec
, description
, oneElement
);
408 // Install the subtree based overrides
410 stream
->dup
= dupTree
;
411 stream
->nextNode
= nextNode
;
412 stream
->free
= freeNodeRS
;
417 ANTLR3_API pANTLR3_REWRITE_RULE_SUBTREE_STREAM
418 antlr3RewriteRuleSubtreeStreamNewAEV(pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_RECOGNIZER rec
, pANTLR3_UINT8 description
, pANTLR3_VECTOR vector
)
420 pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream
;
422 // First job is to create the memory we need.
424 stream
= antlr3RewriteRuleElementStreamNewAEV(adaptor
, rec
, description
, vector
);
431 // Install the subtree based overrides
433 stream
->dup
= dupTree
;
434 stream
->nextNode
= nextNode
;
435 stream
->free
= freeNodeRS
;
439 // Node rewrite stream ...
441 ANTLR3_API pANTLR3_REWRITE_RULE_NODE_STREAM
442 antlr3RewriteRuleNODEStreamNewAE(pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_RECOGNIZER rec
, pANTLR3_UINT8 description
)
444 pANTLR3_REWRITE_RULE_NODE_STREAM stream
;
446 // First job is to create the memory we need.
448 stream
= antlr3RewriteRuleElementStreamNewAE(adaptor
, rec
, description
);
455 // Install the node based overrides
457 stream
->dup
= dupTreeNode
;
458 stream
->toTree
= toTreeNode
;
459 stream
->nextNode
= nextNodeNode
;
460 stream
->free
= freeNodeRS
;
465 ANTLR3_API pANTLR3_REWRITE_RULE_NODE_STREAM
466 antlr3RewriteRuleNODEStreamNewAEE(pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_RECOGNIZER rec
, pANTLR3_UINT8 description
, void * oneElement
)
468 pANTLR3_REWRITE_RULE_NODE_STREAM stream
;
470 // First job is to create the memory we need.
472 stream
= antlr3RewriteRuleElementStreamNewAEE(adaptor
, rec
, description
, oneElement
);
474 // Install the node based overrides
476 stream
->dup
= dupTreeNode
;
477 stream
->toTree
= toTreeNode
;
478 stream
->nextNode
= nextNodeNode
;
479 stream
->free
= freeNodeRS
;
484 ANTLR3_API pANTLR3_REWRITE_RULE_NODE_STREAM
485 antlr3RewriteRuleNODEStreamNewAEV(pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_RECOGNIZER rec
, pANTLR3_UINT8 description
, pANTLR3_VECTOR vector
)
487 pANTLR3_REWRITE_RULE_NODE_STREAM stream
;
489 // First job is to create the memory we need.
491 stream
= antlr3RewriteRuleElementStreamNewAEV(adaptor
, rec
, description
, vector
);
493 // Install the Node based overrides
495 stream
->dup
= dupTreeNode
;
496 stream
->toTree
= toTreeNode
;
497 stream
->nextNode
= nextNodeNode
;
498 stream
->free
= freeNodeRS
;
503 //----------------------------------------------------------------------
504 // Static support functions
506 /// Reset the condition of this stream so that it appears we have
507 /// not consumed any of its elements. Elements themselves are untouched.
510 reset (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream
)
512 stream
->dirty
= ANTLR3_TRUE
;
516 // Add a new pANTLR3_BASE_TREE to this stream
519 add (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream
, void * el
, void (ANTLR3_CDECL
*freePtr
)(void *))
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
529 if (stream
->elements
!= NULL
&& stream
->elements
->count
> 0)
531 // We already have >1 entries in the stream. So we can just add this new element to the existing
534 vectorAdd(stream
->elements
, el
, freePtr
);
537 if (stream
->singleElement
== NULL
)
539 stream
->singleElement
= el
;
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
546 if (stream
->elements
== NULL
)
548 pANTLR3_VECTOR_FACTORY factory
= ((pANTLR3_COMMON_TREE_ADAPTOR
)(stream
->adaptor
->super
))->arboretum
->vFactory
;
551 stream
->elements
= factory
->newVector(factory
);
552 stream
->freeElements
= ANTLR3_TRUE
; // We 'ummed it, so we play it son.
555 vectorAdd(stream
->elements
, stream
->singleElement
, freePtr
);
556 vectorAdd(stream
->elements
, el
, freePtr
);
557 stream
->singleElement
= NULL
;
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).
567 static pANTLR3_BASE_TREE
568 nextTree(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream
)
573 n
= stream
->size(stream
);
575 if ( stream
->dirty
|| (stream
->cursor
>=n
&& n
==1) )
577 // if out of elements and size is 1, dup
579 el
= stream
->_next(stream
);
580 return stream
->dup(stream
, el
);
583 // test size above then fetch
585 el
= stream
->_next(stream
);
589 /// Return the next element for a caller that wants just the token
592 nextToken (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream
)
594 return stream
->_next(stream
);
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].
601 next (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream
)
605 s
= stream
->size(stream
);
606 if (stream
->cursor
>= s
&& s
== 1)
608 pANTLR3_BASE_TREE el
;
610 el
= stream
->_next(stream
);
612 return stream
->dup(stream
, el
);
615 return stream
->_next(stream
);
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.
625 _next (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream
)
630 n
= stream
->size(stream
);
634 // This means that the stream is empty
636 return NULL
; // Caller must cope with this
639 // Traversed all the available elements already?
641 if (stream
->cursor
>= n
)
645 // Special case when size is single element, it will just dup a lot
647 return stream
->toTree(stream
, stream
->singleElement
);
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.
654 return NULL
; // Caller must cope with this
657 // Elements available either for duping or just available
659 if (stream
->singleElement
!= NULL
)
661 stream
->cursor
++; // Cursor advances even for single element as this tells us to dup()
662 return stream
->toTree(stream
, stream
->singleElement
);
665 // More than just a single element so we extract it from the
668 t
= stream
->toTree(stream
, vectorGet(stream
->elements
, stream
->cursor
));
673 #ifdef ANTLR3_WINDOWS
674 #pragma warning(push)
675 #pragma warning(disable : 4100)
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().
682 dupTok (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream
, void * el
)
684 ANTLR3_FPRINTF(stderr
, "dup() cannot be called on a token rewrite stream!!");
687 #ifdef ANTLR3_WINDOWS
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().
696 dupTree (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream
, void * element
)
698 return stream
->adaptor
->dupNode(stream
->adaptor
, (pANTLR3_BASE_TREE
)element
);
701 #ifdef ANTLR3_WINDOWS
702 #pragma warning(push)
703 #pragma warning(disable : 4100)
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().
710 dupTreeNode (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream
, void * element
)
712 ANTLR3_FPRINTF(stderr
, "dup() cannot be called on a node rewrite stream!!!");
717 /// We don;t explicitly convert to a tree unless the call goes to
718 /// nextTree, which means rewrites are heterogeneous
720 static pANTLR3_BASE_TREE
721 toTree (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream
, void * element
)
723 return (pANTLR3_BASE_TREE
)element
;
725 #ifdef ANTLR3_WINDOWS
729 /// Ensure stream emits trees; tokens must be converted to AST nodes.
730 /// AST nodes can be passed through unmolested.
732 #ifdef ANTLR3_WINDOWS
733 #pragma warning(push)
734 #pragma warning(disable : 4100)
737 static pANTLR3_BASE_TREE
738 toTreeNode (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream
, void * element
)
740 return stream
->adaptor
->dupNode(stream
->adaptor
, (pANTLR3_BASE_TREE
)element
);
743 #ifdef ANTLR3_WINDOWS
747 /// Returns ANTLR3_TRUE if there is a next element available
749 static ANTLR3_BOOLEAN
750 hasNext (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream
)
752 if ( (stream
->singleElement
!= NULL
&& stream
->cursor
< 1)
753 || (stream
->elements
!= NULL
&& stream
->cursor
< stream
->elements
->count
))
763 /// Get the next token from the list and create a node for it
764 /// This is the implementation for token streams.
766 static pANTLR3_BASE_TREE
767 nextNodeToken(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream
)
769 return stream
->adaptor
->create(stream
->adaptor
, stream
->_next(stream
));
772 static pANTLR3_BASE_TREE
773 nextNodeNode(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream
)
775 return stream
->_next(stream
);
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.
784 /// Referencing to a rule result twice is ok; dup entire tree as
785 /// we can't be adding trees; e.g., expr expr.
787 static pANTLR3_BASE_TREE
788 nextNode (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream
)
792 pANTLR3_BASE_TREE el
= stream
->_next(stream
);
794 n
= stream
->size(stream
);
795 if (stream
->dirty
== ANTLR3_TRUE
|| (stream
->cursor
> n
&& n
== 1))
797 // We are out of elements and the size is 1, which means we just
798 // dup the node that we have
800 return stream
->adaptor
->dupNode(stream
->adaptor
, el
);
803 // We were not out of nodes, so the one we received is the one to return
808 /// Number of elements available in the stream
811 size (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream
)
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
819 if (stream
->singleElement
!= NULL
)
825 if (stream
->elements
!= NULL
)
827 return (ANTLR3_UINT32
)(stream
->elements
->count
);
833 /// Returns the description string if there is one available (check for NULL).
836 getDescription (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream
)
838 if (stream
->elementDescription
== NULL
)
840 stream
->elementDescription
= "<unknown source>";
843 return stream
->elementDescription
;