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