]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.databoard/cpp/DataBoardTest/libantlr3c-3.2/src/antlr3rewritestreams.c
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.databoard / cpp / DataBoardTest / libantlr3c-3.2 / src / antlr3rewritestreams.c
1 /// \file\r
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
5 ///\r
6 \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
11 //\r
12 // All rights reserved.\r
13 //\r
14 // Redistribution and use in source and binary forms, with or without\r
15 // modification, are permitted provided that the following conditions\r
16 // are met:\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
24 //\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
35 \r
36 #include    <antlr3rewritestreams.h>\r
37 \r
38 // Static support function forward declarations for the stream types.\r
39 //\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
59 \r
60 \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
63 //\r
64 static void\r
65 freeRS  (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)\r
66 {\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
71         //\r
72         if      (stream->elements != NULL)\r
73         {\r
74                 // Factory generated vectors can be returned to the\r
75                 // vector factory for later reuse.\r
76                 //\r
77                 if      (stream->elements->factoryMade == ANTLR3_TRUE)\r
78                 {\r
79                         pANTLR3_VECTOR_FACTORY factory = ((pANTLR3_COMMON_TREE_ADAPTOR)(stream->adaptor->super))->arboretum->vFactory;\r
80                         factory->returnVector(factory, stream->elements);\r
81 \r
82                         stream->elements = NULL;\r
83                 } \r
84                 else\r
85                 {\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
88                         //\r
89                         stream->elements->clear(stream->elements);\r
90                         stream->freeElements = ANTLR3_TRUE;\r
91                 }\r
92         }\r
93         else\r
94         {\r
95                 stream->freeElements = ANTLR3_FALSE; // Just in case\r
96         }\r
97 \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
101         //\r
102         stream->rec->state->rStreams->add(stream->rec->state->rStreams, stream, (void(*)(void *))expungeRS);\r
103 }\r
104 \r
105 /** Do special nilNode reuse detection for node streams.\r
106  */\r
107 static void\r
108 freeNodeRS(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)\r
109 {\r
110     pANTLR3_BASE_TREE tree;\r
111 \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
119         //\r
120         if      (stream->elements != NULL)\r
121         {\r
122         // We have some elements to traverse\r
123         //\r
124         ANTLR3_UINT32 i;\r
125 \r
126         for (i = 1; i<= stream->elements->count; i++)\r
127         {\r
128             tree = (pANTLR3_BASE_TREE)(stream->elements->elements[i-1].element);\r
129             if  (tree != NULL && tree->isNilNode(tree))\r
130             {\r
131                 // Had to remove this for now, check is not comprehensive enough\r
132                 // tree->reuse(tree);\r
133             }\r
134 \r
135         }\r
136                 // Factory generated vectors can be returned to the\r
137                 // vector factory for later reuse.\r
138                 //\r
139                 if      (stream->elements->factoryMade == ANTLR3_TRUE)\r
140                 {\r
141                         pANTLR3_VECTOR_FACTORY factory = ((pANTLR3_COMMON_TREE_ADAPTOR)(stream->adaptor->super))->arboretum->vFactory;\r
142                         factory->returnVector(factory, stream->elements);\r
143 \r
144                         stream->elements = NULL;\r
145                 } \r
146                 else\r
147                 {\r
148                         stream->elements->clear(stream->elements);\r
149                         stream->freeElements = ANTLR3_TRUE;\r
150                 }\r
151         }\r
152         else\r
153         {\r
154         if  (stream->singleElement != NULL)\r
155         {\r
156             tree = (pANTLR3_BASE_TREE)(stream->singleElement);\r
157             if  (tree->isNilNode(tree))\r
158             {\r
159                 // Had to remove this for now, check is not comprehensive enough\r
160               //   tree->reuse(tree);\r
161             }\r
162         }\r
163         stream->singleElement = NULL;\r
164                 stream->freeElements = ANTLR3_FALSE; // Just in case\r
165         }\r
166 \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
170         //\r
171         stream->rec->state->rStreams->add(stream->rec->state->rStreams, stream, (void(*)(void *))expungeRS);\r
172 }\r
173 static void\r
174 expungeRS(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)\r
175 {\r
176 \r
177         if (stream->freeElements == ANTLR3_TRUE && stream->elements != NULL)\r
178         {\r
179                 stream->elements->free(stream->elements);\r
180         }\r
181         ANTLR3_FREE(stream);\r
182 }\r
183 \r
184 // Functions for creating streams\r
185 //\r
186 static  pANTLR3_REWRITE_RULE_ELEMENT_STREAM \r
187 antlr3RewriteRuleElementStreamNewAE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description)\r
188 {\r
189         pANTLR3_REWRITE_RULE_ELEMENT_STREAM     stream;\r
190 \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
194         //\r
195         if      (rec->state->rStreams->count > 0)\r
196         {\r
197                 // Remove the entry from the vector. We do not\r
198                 // cause it to be freed by using remove.\r
199                 //\r
200                 stream = rec->state->rStreams->remove(rec->state->rStreams, rec->state->rStreams->count - 1);\r
201 \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
205                 //\r
206         }\r
207         else\r
208         {\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
211                 //\r
212                 stream  = (pANTLR3_REWRITE_RULE_ELEMENT_STREAM) ANTLR3_MALLOC((size_t)(sizeof(ANTLR3_REWRITE_RULE_ELEMENT_STREAM)));\r
213 \r
214                 if      (stream == NULL)\r
215                 {\r
216                         return  NULL;\r
217                 }\r
218                 stream->elements                = NULL;\r
219                 stream->freeElements    = ANTLR3_FALSE;\r
220         }\r
221 \r
222         // Populate the generic interface\r
223         //\r
224         stream->rec                             = rec;\r
225         stream->reset                   = reset;\r
226         stream->add                             = add;\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
238 \r
239         // Reset the stream to empty.\r
240         //\r
241 \r
242         stream->cursor                  = 0;\r
243         stream->dirty                   = ANTLR3_FALSE;\r
244 \r
245         // Install the description\r
246         //\r
247         stream->elementDescription      = description;\r
248 \r
249         // Install the adaptor\r
250         //\r
251         stream->adaptor         = adaptor;\r
252 \r
253         return stream;\r
254 }\r
255 \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
258 {\r
259         pANTLR3_REWRITE_RULE_ELEMENT_STREAM     stream;\r
260 \r
261         // First job is to create the memory we need.\r
262         //\r
263         stream  = antlr3RewriteRuleElementStreamNewAE(adaptor, rec, description);\r
264 \r
265         if (stream == NULL)\r
266         {\r
267                 return NULL;\r
268         }\r
269 \r
270         // Stream seems good so we need to add the supplied element\r
271         //\r
272         if      (oneElement != NULL)\r
273         {\r
274                 stream->add(stream, oneElement, NULL);\r
275         }\r
276         return stream;\r
277 }\r
278 \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
281 {\r
282         pANTLR3_REWRITE_RULE_ELEMENT_STREAM     stream;\r
283 \r
284         // First job is to create the memory we need.\r
285         //\r
286         stream  = antlr3RewriteRuleElementStreamNewAE(adaptor, rec, description);\r
287 \r
288         if (stream == NULL)\r
289         {\r
290                 return stream;\r
291         }\r
292 \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
295         // vector.\r
296         //\r
297         if      (stream->elements != NULL && stream->elements->factoryMade == ANTLR3_FALSE && stream->freeElements == ANTLR3_TRUE )\r
298         {\r
299                 stream->elements->free(stream->elements);\r
300         }\r
301         stream->elements                = vector;\r
302         stream->freeElements    = ANTLR3_FALSE;\r
303         return stream;\r
304 }\r
305 \r
306 // Token rewrite stream ...\r
307 //\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
310 {\r
311         pANTLR3_REWRITE_RULE_TOKEN_STREAM       stream;\r
312 \r
313         // First job is to create the memory we need.\r
314         //\r
315         stream  = antlr3RewriteRuleElementStreamNewAE(adaptor, rec, description);\r
316 \r
317         if (stream == NULL)\r
318         {\r
319                 return stream;\r
320         }\r
321 \r
322         // Install the token based overrides\r
323         //\r
324         stream->dup                     = dupTok;\r
325         stream->nextNode        = nextNodeToken;\r
326 \r
327         // No nextNode implementation for a token rewrite stream\r
328         //\r
329         return stream;\r
330 }\r
331 \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
334 {\r
335         pANTLR3_REWRITE_RULE_TOKEN_STREAM       stream;\r
336 \r
337         // First job is to create the memory we need.\r
338         //\r
339         stream  = antlr3RewriteRuleElementStreamNewAEE(adaptor, rec, description, oneElement);\r
340 \r
341         // Install the token based overrides\r
342         //\r
343         stream->dup                     = dupTok;\r
344         stream->nextNode        = nextNodeToken;\r
345 \r
346         // No nextNode implementation for a token rewrite stream\r
347         //\r
348         return stream;\r
349 }\r
350 \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
353 {\r
354         pANTLR3_REWRITE_RULE_TOKEN_STREAM       stream;\r
355 \r
356         // First job is to create the memory we need.\r
357         //\r
358         stream  = antlr3RewriteRuleElementStreamNewAEV(adaptor, rec, description, vector);\r
359 \r
360         // Install the token based overrides\r
361         //\r
362         stream->dup                     = dupTok;\r
363         stream->nextNode        = nextNodeToken;\r
364 \r
365         // No nextNode implementation for a token rewrite stream\r
366         //\r
367         return stream;\r
368 }\r
369 \r
370 // Subtree rewrite stream\r
371 //\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
374 {\r
375         pANTLR3_REWRITE_RULE_SUBTREE_STREAM     stream;\r
376 \r
377         // First job is to create the memory we need.\r
378         //\r
379         stream  = antlr3RewriteRuleElementStreamNewAE(adaptor, rec, description);\r
380 \r
381         if (stream == NULL)\r
382         {\r
383                 return stream;\r
384         }\r
385 \r
386         // Install the subtree based overrides\r
387         //\r
388         stream->dup                     = dupTree;\r
389         stream->nextNode        = nextNode;\r
390     stream->free        = freeNodeRS;\r
391         return stream;\r
392 \r
393 }\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
396 {\r
397         pANTLR3_REWRITE_RULE_SUBTREE_STREAM     stream;\r
398 \r
399         // First job is to create the memory we need.\r
400         //\r
401         stream  = antlr3RewriteRuleElementStreamNewAEE(adaptor, rec, description, oneElement);\r
402 \r
403         if (stream == NULL)\r
404         {\r
405                 return stream;\r
406         }\r
407 \r
408         // Install the subtree based overrides\r
409         //\r
410         stream->dup                     = dupTree;\r
411         stream->nextNode        = nextNode;\r
412     stream->free        = freeNodeRS;\r
413 \r
414         return stream;\r
415 }\r
416 \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
419 {\r
420         pANTLR3_REWRITE_RULE_SUBTREE_STREAM     stream;\r
421 \r
422         // First job is to create the memory we need.\r
423         //\r
424         stream  = antlr3RewriteRuleElementStreamNewAEV(adaptor, rec, description, vector);\r
425 \r
426         if (stream == NULL)\r
427         {\r
428                 return NULL;\r
429         }\r
430 \r
431         // Install the subtree based overrides\r
432         //\r
433         stream->dup                     = dupTree;\r
434         stream->nextNode        = nextNode;\r
435     stream->free        = freeNodeRS;\r
436 \r
437         return stream;\r
438 }\r
439 // Node rewrite stream ...\r
440 //\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
443 {\r
444         pANTLR3_REWRITE_RULE_NODE_STREAM        stream;\r
445 \r
446         // First job is to create the memory we need.\r
447         //\r
448         stream  = antlr3RewriteRuleElementStreamNewAE(adaptor, rec, description);\r
449 \r
450         if (stream == NULL)\r
451         {\r
452                 return stream;\r
453         }\r
454 \r
455         // Install the node based overrides\r
456         //\r
457         stream->dup                     = dupTreeNode;\r
458         stream->toTree          = toTreeNode;\r
459         stream->nextNode        = nextNodeNode;\r
460     stream->free        = freeNodeRS;\r
461 \r
462         return stream;\r
463 }\r
464 \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
467 {\r
468         pANTLR3_REWRITE_RULE_NODE_STREAM        stream;\r
469 \r
470         // First job is to create the memory we need.\r
471         //\r
472         stream  = antlr3RewriteRuleElementStreamNewAEE(adaptor, rec, description, oneElement);\r
473 \r
474         // Install the node based overrides\r
475         //\r
476         stream->dup                     = dupTreeNode;\r
477         stream->toTree          = toTreeNode;\r
478         stream->nextNode        = nextNodeNode;\r
479     stream->free        = freeNodeRS;\r
480 \r
481         return stream;\r
482 }\r
483 \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
486 {\r
487         pANTLR3_REWRITE_RULE_NODE_STREAM        stream;\r
488 \r
489         // First job is to create the memory we need.\r
490         //\r
491         stream  = antlr3RewriteRuleElementStreamNewAEV(adaptor, rec, description, vector);\r
492 \r
493         // Install the Node based overrides\r
494         //\r
495         stream->dup                     = dupTreeNode;\r
496         stream->toTree          = toTreeNode;\r
497         stream->nextNode        = nextNodeNode;\r
498     stream->free        = freeNodeRS;\r
499     \r
500         return stream;\r
501 }\r
502 \r
503 //----------------------------------------------------------------------\r
504 // Static support functions \r
505 \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
508 ///\r
509 static void             \r
510 reset    (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)\r
511 {\r
512         stream->dirty   = ANTLR3_TRUE;\r
513         stream->cursor  = 0;\r
514 }\r
515 \r
516 // Add a new pANTLR3_BASE_TREE to this stream\r
517 //\r
518 static void             \r
519 add         (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * el, void (ANTLR3_CDECL *freePtr)(void *))\r
520 {\r
521         if (el== NULL)\r
522         {\r
523                 return;\r
524         }\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
528         //\r
529         if (stream->elements != NULL && stream->elements->count > 0)\r
530         {\r
531                 // We already have >1 entries in the stream. So we can just add this new element to the existing\r
532                 // collection. \r
533                 //\r
534                 stream->elements->add(stream->elements, el, freePtr);\r
535                 return;\r
536         }\r
537         if (stream->singleElement == NULL)\r
538         {\r
539                 stream->singleElement = el;\r
540                 return;\r
541         }\r
542 \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
545         //\r
546         if      (stream->elements == NULL)\r
547         {\r
548         pANTLR3_VECTOR_FACTORY factory = ((pANTLR3_COMMON_TREE_ADAPTOR)(stream->adaptor->super))->arboretum->vFactory;\r
549 \r
550         \r
551                 stream->elements                = factory->newVector(factory);\r
552                 stream->freeElements    = ANTLR3_TRUE;                  // We 'ummed it, so we play it son.\r
553         }\r
554     \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
558 \r
559         return;\r
560 }\r
561 \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
566 ///\r
567 static pANTLR3_BASE_TREE\r
568 nextTree(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream) \r
569 {\r
570         ANTLR3_UINT32           n;\r
571         void                    *  el;\r
572 \r
573         n = stream->size(stream);\r
574 \r
575         if ( stream->dirty || (stream->cursor >=n && n==1) ) \r
576         {\r
577                 // if out of elements and size is 1, dup\r
578                 //\r
579                 el = stream->_next(stream);\r
580                 return stream->dup(stream, el);\r
581         }\r
582 \r
583         // test size above then fetch\r
584         //\r
585         el = stream->_next(stream);\r
586         return el;\r
587 }\r
588 \r
589 /// Return the next element for a caller that wants just the token\r
590 ///\r
591 static  void *\r
592 nextToken               (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)\r
593 {\r
594         return stream->_next(stream);\r
595 }\r
596 \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
599 ///\r
600 static void *   \r
601 next        (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)\r
602 {\r
603         ANTLR3_UINT32   s;\r
604 \r
605         s = stream->size(stream);\r
606         if (stream->cursor >= s && s == 1)\r
607         {\r
608                 pANTLR3_BASE_TREE el;\r
609 \r
610                 el = stream->_next(stream);\r
611 \r
612                 return  stream->dup(stream, el);\r
613         }\r
614 \r
615         return stream->_next(stream);\r
616 }\r
617 \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
623 ///\r
624 static void *\r
625 _next    (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)\r
626 {\r
627         ANTLR3_UINT32           n;\r
628         pANTLR3_BASE_TREE       t;\r
629 \r
630         n = stream->size(stream);\r
631 \r
632         if (n == 0)\r
633         {\r
634                 // This means that the stream is empty\r
635                 //\r
636                 return NULL;    // Caller must cope with this\r
637         }\r
638 \r
639         // Traversed all the available elements already?\r
640         //\r
641         if (stream->cursor >= n)\r
642         {\r
643                 if (n == 1)\r
644                 {\r
645                         // Special case when size is single element, it will just dup a lot\r
646                         //\r
647                         return stream->toTree(stream, stream->singleElement);\r
648                 }\r
649 \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
653                 //\r
654                 return NULL;    // Caller must cope with this\r
655         }\r
656 \r
657         // Elements available either for duping or just available\r
658         //\r
659         if (stream->singleElement != NULL)\r
660         {\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
663         }\r
664 \r
665         // More than just a single element so we extract it from the \r
666         // vector.\r
667         //\r
668         t = stream->toTree(stream, stream->elements->get(stream->elements, stream->cursor));\r
669         stream->cursor++;\r
670         return t;\r
671 }\r
672 \r
673 #ifdef ANTLR3_WINDOWS\r
674 #pragma warning(push)\r
675 #pragma warning(disable : 4100)\r
676 #endif\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
680 ///\r
681 static void *   \r
682 dupTok      (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * el)\r
683 {\r
684         ANTLR3_FPRINTF(stderr, "dup() cannot be called on a token rewrite stream!!");\r
685         return NULL;\r
686 }\r
687 #ifdef ANTLR3_WINDOWS\r
688 #pragma warning(pop)\r
689 #endif\r
690 \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
694 ///\r
695 static void *   \r
696 dupTree     (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * element)\r
697 {\r
698         return stream->adaptor->dupNode(stream->adaptor, (pANTLR3_BASE_TREE)element);\r
699 }\r
700 \r
701 #ifdef ANTLR3_WINDOWS\r
702 #pragma warning(push)\r
703 #pragma warning(disable : 4100)\r
704 #endif\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
708 ///\r
709 static void *   \r
710 dupTreeNode         (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * element)\r
711 {\r
712         ANTLR3_FPRINTF(stderr, "dup() cannot be called on a node rewrite stream!!!");\r
713         return NULL;\r
714 }\r
715 \r
716 \r
717 /// We don;t explicitly convert to a tree unless the call goes to \r
718 /// nextTree, which means rewrites are heterogeneous \r
719 ///\r
720 static pANTLR3_BASE_TREE        \r
721 toTree   (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * element)\r
722 {\r
723         return (pANTLR3_BASE_TREE)element;\r
724 }\r
725 #ifdef ANTLR3_WINDOWS\r
726 #pragma warning(pop)\r
727 #endif\r
728 \r
729 /// Ensure stream emits trees; tokens must be converted to AST nodes.\r
730 /// AST nodes can be passed through unmolested.\r
731 ///\r
732 #ifdef ANTLR3_WINDOWS\r
733 #pragma warning(push)\r
734 #pragma warning(disable : 4100)\r
735 #endif\r
736 \r
737 static pANTLR3_BASE_TREE        \r
738 toTreeNode   (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * element)\r
739 {\r
740         return stream->adaptor->dupNode(stream->adaptor, (pANTLR3_BASE_TREE)element);\r
741 }\r
742 \r
743 #ifdef ANTLR3_WINDOWS\r
744 #pragma warning(pop)\r
745 #endif\r
746 \r
747 /// Returns ANTLR3_TRUE if there is a next element available\r
748 ///\r
749 static ANTLR3_BOOLEAN   \r
750 hasNext  (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)\r
751 {\r
752         if (    (stream->singleElement != NULL && stream->cursor < 1)\r
753                 ||      (stream->elements != NULL && stream->cursor < stream->elements->size(stream->elements)))\r
754         {\r
755                 return ANTLR3_TRUE;\r
756         }\r
757         else\r
758         {\r
759                 return ANTLR3_FALSE;\r
760         }\r
761 }\r
762 \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
765 ///\r
766 static pANTLR3_BASE_TREE\r
767 nextNodeToken(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)\r
768 {\r
769         return stream->adaptor->create(stream->adaptor, stream->_next(stream));\r
770 }\r
771 \r
772 static pANTLR3_BASE_TREE\r
773 nextNodeNode(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)\r
774 {\r
775         return stream->_next(stream);\r
776 }\r
777 \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
783 ///\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
786 ///\r
787 static pANTLR3_BASE_TREE        \r
788 nextNode (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)\r
789 {\r
790 \r
791         ANTLR3_UINT32   n;\r
792         pANTLR3_BASE_TREE       el = stream->_next(stream);\r
793 \r
794         n = stream->size(stream);\r
795         if (stream->dirty == ANTLR3_TRUE || (stream->cursor > n && n == 1))\r
796         {\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
799                 //\r
800                 return  stream->adaptor->dupNode(stream->adaptor, el);\r
801         }\r
802 \r
803         // We were not out of nodes, so the one we received is the one to return\r
804         //\r
805         return  el;\r
806 }\r
807 \r
808 /// Number of elements available in the stream\r
809 ///\r
810 static ANTLR3_UINT32    \r
811 size        (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)\r
812 {\r
813         ANTLR3_UINT32   n = 0;\r
814 \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
818         ///\r
819         if (stream->singleElement != NULL)\r
820         {\r
821                 n = 1;\r
822         }\r
823         else\r
824         {\r
825                 if (stream->elements != NULL)\r
826                 {\r
827                         return (ANTLR3_UINT32)(stream->elements->count);\r
828                 }\r
829         }\r
830         return n;\r
831 }\r
832 \r
833 /// Returns the description string if there is one available (check for NULL).\r
834 ///\r
835 static void *   \r
836 getDescription  (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)\r
837 {\r
838         if (stream->elementDescription == NULL)\r
839         {\r
840                 stream->elementDescription = "<unknown source>";\r
841         }\r
842 \r
843         return  stream->elementDescription;\r
844 }\r