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