2 /// Defines the implementation of the common node stream the default
\r
3 /// tree node stream used by ANTLR.
\r
6 // [The "BSD licence"]
\r
7 // Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC
\r
8 // http://www.temporal-wave.com
\r
9 // http://www.linkedin.com/in/jimidle
\r
11 // All rights reserved.
\r
13 // Redistribution and use in source and binary forms, with or without
\r
14 // modification, are permitted provided that the following conditions
\r
16 // 1. Redistributions of source code must retain the above copyright
\r
17 // notice, this list of conditions and the following disclaimer.
\r
18 // 2. Redistributions in binary form must reproduce the above copyright
\r
19 // notice, this list of conditions and the following disclaimer in the
\r
20 // documentation and/or other materials provided with the distribution.
\r
21 // 3. The name of the author may not be used to endorse or promote products
\r
22 // derived from this software without specific prior written permission.
\r
24 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
\r
25 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
\r
26 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
\r
27 // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
\r
28 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
\r
29 // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
\r
30 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
\r
31 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
\r
32 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
\r
33 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
35 #include <antlr3commontreenodestream.h>
\r
37 #ifdef ANTLR3_WINDOWS
\r
38 #pragma warning( disable : 4100 )
\r
41 // COMMON TREE STREAM API
\r
43 static void addNavigationNode (pANTLR3_COMMON_TREE_NODE_STREAM ctns, ANTLR3_UINT32 ttype);
\r
44 static ANTLR3_BOOLEAN hasUniqueNavigationNodes (pANTLR3_COMMON_TREE_NODE_STREAM ctns);
\r
45 static pANTLR3_BASE_TREE newDownNode (pANTLR3_COMMON_TREE_NODE_STREAM ctns);
\r
46 static pANTLR3_BASE_TREE newUpNode (pANTLR3_COMMON_TREE_NODE_STREAM ctns);
\r
47 static void reset (pANTLR3_COMMON_TREE_NODE_STREAM ctns);
\r
48 static void push (pANTLR3_COMMON_TREE_NODE_STREAM ctns, ANTLR3_INT32 index);
\r
49 static ANTLR3_INT32 pop (pANTLR3_COMMON_TREE_NODE_STREAM ctns);
\r
50 //static ANTLR3_INT32 index (pANTLR3_COMMON_TREE_NODE_STREAM ctns);
\r
51 static ANTLR3_UINT32 getLookaheadSize (pANTLR3_COMMON_TREE_NODE_STREAM ctns);
\r
52 // TREE NODE STREAM API
\r
54 static pANTLR3_BASE_TREE_ADAPTOR getTreeAdaptor (pANTLR3_TREE_NODE_STREAM tns);
\r
55 static pANTLR3_BASE_TREE getTreeSource (pANTLR3_TREE_NODE_STREAM tns);
\r
56 static pANTLR3_BASE_TREE _LT (pANTLR3_TREE_NODE_STREAM tns, ANTLR3_INT32 k);
\r
57 static pANTLR3_BASE_TREE get (pANTLR3_TREE_NODE_STREAM tns, ANTLR3_INT32 k);
\r
58 static void setUniqueNavigationNodes (pANTLR3_TREE_NODE_STREAM tns, ANTLR3_BOOLEAN uniqueNavigationNodes);
\r
59 static pANTLR3_STRING toString (pANTLR3_TREE_NODE_STREAM tns);
\r
60 static pANTLR3_STRING toStringSS (pANTLR3_TREE_NODE_STREAM tns, pANTLR3_BASE_TREE start, pANTLR3_BASE_TREE stop);
\r
61 static void toStringWork (pANTLR3_TREE_NODE_STREAM tns, pANTLR3_BASE_TREE start, pANTLR3_BASE_TREE stop, pANTLR3_STRING buf);
\r
62 static void replaceChildren (pANTLR3_TREE_NODE_STREAM tns, pANTLR3_BASE_TREE parent, ANTLR3_INT32 startChildIndex, ANTLR3_INT32 stopChildIndex, pANTLR3_BASE_TREE t);
\r
66 static void consume (pANTLR3_INT_STREAM is);
\r
67 static ANTLR3_MARKER tindex (pANTLR3_INT_STREAM is);
\r
68 static ANTLR3_UINT32 _LA (pANTLR3_INT_STREAM is, ANTLR3_INT32 i);
\r
69 static ANTLR3_MARKER mark (pANTLR3_INT_STREAM is);
\r
70 static void release (pANTLR3_INT_STREAM is, ANTLR3_MARKER marker);
\r
71 static void rewindMark (pANTLR3_INT_STREAM is, ANTLR3_MARKER marker);
\r
72 static void rewindLast (pANTLR3_INT_STREAM is);
\r
73 static void seek (pANTLR3_INT_STREAM is, ANTLR3_MARKER index);
\r
74 static ANTLR3_UINT32 size (pANTLR3_INT_STREAM is);
\r
79 static void fillBuffer (pANTLR3_COMMON_TREE_NODE_STREAM ctns, pANTLR3_BASE_TREE t);
\r
80 static void fillBufferRoot (pANTLR3_COMMON_TREE_NODE_STREAM ctns);
\r
84 static void antlr3TreeNodeStreamFree (pANTLR3_TREE_NODE_STREAM tns);
\r
85 static void antlr3CommonTreeNodeStreamFree (pANTLR3_COMMON_TREE_NODE_STREAM ctns);
\r
87 ANTLR3_API pANTLR3_TREE_NODE_STREAM
\r
88 antlr3TreeNodeStreamNew()
\r
90 pANTLR3_TREE_NODE_STREAM stream;
\r
92 // Memory for the interface structure
\r
94 stream = (pANTLR3_TREE_NODE_STREAM) ANTLR3_CALLOC(1, sizeof(ANTLR3_TREE_NODE_STREAM));
\r
101 // Install basic API
\r
103 stream->replaceChildren = replaceChildren;
\r
104 stream->free = antlr3TreeNodeStreamFree;
\r
110 antlr3TreeNodeStreamFree(pANTLR3_TREE_NODE_STREAM stream)
\r
112 ANTLR3_FREE(stream);
\r
115 ANTLR3_API pANTLR3_COMMON_TREE_NODE_STREAM
\r
116 antlr3CommonTreeNodeStreamNewTree(pANTLR3_BASE_TREE tree, ANTLR3_UINT32 hint)
\r
118 pANTLR3_COMMON_TREE_NODE_STREAM stream;
\r
120 stream = antlr3CommonTreeNodeStreamNew(tree->strFactory, hint);
\r
122 if (stream == NULL)
\r
126 stream->root = tree;
\r
131 ANTLR3_API pANTLR3_COMMON_TREE_NODE_STREAM
\r
132 antlr3CommonTreeNodeStreamNewStream(pANTLR3_COMMON_TREE_NODE_STREAM inStream)
\r
134 pANTLR3_COMMON_TREE_NODE_STREAM stream;
\r
136 // Memory for the interface structure
\r
138 stream = (pANTLR3_COMMON_TREE_NODE_STREAM) ANTLR3_CALLOC(1, sizeof(ANTLR3_COMMON_TREE_NODE_STREAM));
\r
140 if (stream == NULL)
\r
145 // Copy in all the reusable parts of the originating stream and create new
\r
146 // pieces where necessary.
\r
149 // String factory for tree walker
\r
151 stream->stringFactory = inStream->stringFactory;
\r
153 // Create an adaptor for the common tree node stream
\r
155 stream->adaptor = inStream->adaptor;
\r
157 // Create space for the tree node stream interface
\r
159 stream->tnstream = antlr3TreeNodeStreamNew();
\r
161 if (stream->tnstream == NULL)
\r
163 stream->free (stream);
\r
168 // Create space for the INT_STREAM interface
\r
170 stream->tnstream->istream = antlr3IntStreamNew();
\r
172 if (stream->tnstream->istream == NULL)
\r
174 stream->tnstream->free (stream->tnstream);
\r
175 stream->free (stream);
\r
180 // Install the common tree node stream API
\r
182 stream->addNavigationNode = addNavigationNode;
\r
183 stream->hasUniqueNavigationNodes = hasUniqueNavigationNodes;
\r
184 stream->newDownNode = newDownNode;
\r
185 stream->newUpNode = newUpNode;
\r
186 stream->reset = reset;
\r
187 stream->push = push;
\r
189 stream->getLookaheadSize = getLookaheadSize;
\r
191 stream->free = antlr3CommonTreeNodeStreamFree;
\r
193 // Install the tree node stream API
\r
195 stream->tnstream->getTreeAdaptor = getTreeAdaptor;
\r
196 stream->tnstream->getTreeSource = getTreeSource;
\r
197 stream->tnstream->_LT = _LT;
\r
198 stream->tnstream->setUniqueNavigationNodes = setUniqueNavigationNodes;
\r
199 stream->tnstream->toString = toString;
\r
200 stream->tnstream->toStringSS = toStringSS;
\r
201 stream->tnstream->toStringWork = toStringWork;
\r
202 stream->tnstream->get = get;
\r
204 // Install INT_STREAM interface
\r
206 stream->tnstream->istream->consume = consume;
\r
207 stream->tnstream->istream->index = tindex;
\r
208 stream->tnstream->istream->_LA = _LA;
\r
209 stream->tnstream->istream->mark = mark;
\r
210 stream->tnstream->istream->release = release;
\r
211 stream->tnstream->istream->rewind = rewindMark;
\r
212 stream->tnstream->istream->rewindLast = rewindLast;
\r
213 stream->tnstream->istream->seek = seek;
\r
214 stream->tnstream->istream->size = size;
\r
216 // Initialize data elements of INT stream
\r
218 stream->tnstream->istream->type = ANTLR3_COMMONTREENODE;
\r
219 stream->tnstream->istream->super = (stream->tnstream);
\r
221 // Initialize data elements of TREE stream
\r
223 stream->tnstream->ctns = stream;
\r
225 // Initialize data elements of the COMMON TREE NODE stream
\r
227 stream->super = NULL;
\r
228 stream->uniqueNavigationNodes = ANTLR3_FALSE;
\r
229 stream->markers = NULL;
\r
230 stream->nodeStack = inStream->nodeStack;
\r
232 // Create the node list map
\r
234 stream->nodes = antlr3VectorNew(DEFAULT_INITIAL_BUFFER_SIZE);
\r
237 // Install the navigation nodes
\r
240 // Install the navigation nodes
\r
242 antlr3SetCTAPI(&(stream->UP));
\r
243 antlr3SetCTAPI(&(stream->DOWN));
\r
244 antlr3SetCTAPI(&(stream->EOF_NODE));
\r
245 antlr3SetCTAPI(&(stream->INVALID_NODE));
\r
247 stream->UP.token = inStream->UP.token;
\r
248 inStream->UP.token->strFactory = stream->stringFactory;
\r
249 stream->DOWN.token = inStream->DOWN.token;
\r
250 inStream->DOWN.token->strFactory = stream->stringFactory;
\r
251 stream->EOF_NODE.token = inStream->EOF_NODE.token;
\r
252 inStream->EOF_NODE.token->strFactory = stream->stringFactory;
\r
253 stream->INVALID_NODE.token = inStream->INVALID_NODE.token;
\r
254 inStream->INVALID_NODE.token->strFactory= stream->stringFactory;
\r
256 // Reuse the root tree of the originating stream
\r
258 stream->root = inStream->root;
\r
260 // Signal that this is a rewriting stream so we don't
\r
261 // free the originating tree. Anything that we rewrite or
\r
262 // duplicate here will be done through the adaptor or
\r
263 // the original tree factory.
\r
265 stream->isRewriter = ANTLR3_TRUE;
\r
269 ANTLR3_API pANTLR3_COMMON_TREE_NODE_STREAM
\r
270 antlr3CommonTreeNodeStreamNew(pANTLR3_STRING_FACTORY strFactory, ANTLR3_UINT32 hint)
\r
272 pANTLR3_COMMON_TREE_NODE_STREAM stream;
\r
273 pANTLR3_COMMON_TOKEN token;
\r
275 // Memory for the interface structure
\r
277 stream = (pANTLR3_COMMON_TREE_NODE_STREAM) ANTLR3_CALLOC(1, sizeof(ANTLR3_COMMON_TREE_NODE_STREAM));
\r
279 if (stream == NULL)
\r
284 // String factory for tree walker
\r
286 stream->stringFactory = strFactory;
\r
288 // Create an adaptor for the common tree node stream
\r
290 stream->adaptor = ANTLR3_TREE_ADAPTORNew(strFactory);
\r
292 if (stream->adaptor == NULL)
\r
294 stream->free(stream);
\r
298 // Create space for the tree node stream interface
\r
300 stream->tnstream = antlr3TreeNodeStreamNew();
\r
302 if (stream->tnstream == NULL)
\r
304 stream->adaptor->free (stream->adaptor);
\r
305 stream->free (stream);
\r
310 // Create space for the INT_STREAM interface
\r
312 stream->tnstream->istream = antlr3IntStreamNew();
\r
314 if (stream->tnstream->istream == NULL)
\r
316 stream->adaptor->free (stream->adaptor);
\r
317 stream->tnstream->free (stream->tnstream);
\r
318 stream->free (stream);
\r
323 // Install the common tree node stream API
\r
325 stream->addNavigationNode = addNavigationNode;
\r
326 stream->hasUniqueNavigationNodes = hasUniqueNavigationNodes;
\r
327 stream->newDownNode = newDownNode;
\r
328 stream->newUpNode = newUpNode;
\r
329 stream->reset = reset;
\r
330 stream->push = push;
\r
333 stream->free = antlr3CommonTreeNodeStreamFree;
\r
335 // Install the tree node stream API
\r
337 stream->tnstream->getTreeAdaptor = getTreeAdaptor;
\r
338 stream->tnstream->getTreeSource = getTreeSource;
\r
339 stream->tnstream->_LT = _LT;
\r
340 stream->tnstream->setUniqueNavigationNodes = setUniqueNavigationNodes;
\r
341 stream->tnstream->toString = toString;
\r
342 stream->tnstream->toStringSS = toStringSS;
\r
343 stream->tnstream->toStringWork = toStringWork;
\r
344 stream->tnstream->get = get;
\r
346 // Install INT_STREAM interface
\r
348 stream->tnstream->istream->consume = consume;
\r
349 stream->tnstream->istream->index = tindex;
\r
350 stream->tnstream->istream->_LA = _LA;
\r
351 stream->tnstream->istream->mark = mark;
\r
352 stream->tnstream->istream->release = release;
\r
353 stream->tnstream->istream->rewind = rewindMark;
\r
354 stream->tnstream->istream->rewindLast = rewindLast;
\r
355 stream->tnstream->istream->seek = seek;
\r
356 stream->tnstream->istream->size = size;
\r
358 // Initialize data elements of INT stream
\r
360 stream->tnstream->istream->type = ANTLR3_COMMONTREENODE;
\r
361 stream->tnstream->istream->super = (stream->tnstream);
\r
363 // Initialize data elements of TREE stream
\r
365 stream->tnstream->ctns = stream;
\r
367 // Initialize data elements of the COMMON TREE NODE stream
\r
369 stream->super = NULL;
\r
370 stream->uniqueNavigationNodes = ANTLR3_FALSE;
\r
371 stream->markers = NULL;
\r
372 stream->nodeStack = antlr3StackNew(INITIAL_CALL_STACK_SIZE);
\r
374 // Create the node list map
\r
378 hint = DEFAULT_INITIAL_BUFFER_SIZE;
\r
380 stream->nodes = antlr3VectorNew(hint);
\r
383 // Install the navigation nodes
\r
385 antlr3SetCTAPI(&(stream->UP));
\r
386 antlr3SetCTAPI(&(stream->DOWN));
\r
387 antlr3SetCTAPI(&(stream->EOF_NODE));
\r
388 antlr3SetCTAPI(&(stream->INVALID_NODE));
\r
390 token = antlr3CommonTokenNew(ANTLR3_TOKEN_UP);
\r
391 token->strFactory = strFactory;
\r
392 token->textState = ANTLR3_TEXT_CHARP;
\r
393 token->tokText.chars = (pANTLR3_UCHAR)"UP";
\r
394 stream->UP.token = token;
\r
396 token = antlr3CommonTokenNew(ANTLR3_TOKEN_DOWN);
\r
397 token->strFactory = strFactory;
\r
398 token->textState = ANTLR3_TEXT_CHARP;
\r
399 token->tokText.chars = (pANTLR3_UCHAR)"DOWN";
\r
400 stream->DOWN.token = token;
\r
402 token = antlr3CommonTokenNew(ANTLR3_TOKEN_EOF);
\r
403 token->strFactory = strFactory;
\r
404 token->textState = ANTLR3_TEXT_CHARP;
\r
405 token->tokText.chars = (pANTLR3_UCHAR)"EOF";
\r
406 stream->EOF_NODE.token = token;
\r
408 token = antlr3CommonTokenNew(ANTLR3_TOKEN_INVALID);
\r
409 token->strFactory = strFactory;
\r
410 token->textState = ANTLR3_TEXT_CHARP;
\r
411 token->tokText.chars = (pANTLR3_UCHAR)"INVALID";
\r
412 stream->INVALID_NODE.token = token;
\r
418 /// Free up any resources that belong to this common tree node stream.
\r
420 static void antlr3CommonTreeNodeStreamFree (pANTLR3_COMMON_TREE_NODE_STREAM ctns)
\r
423 // If this is a rewrting stream, then certain resources
\r
424 // belong to the originating node stream and we do not
\r
427 if (ctns->isRewriter != ANTLR3_TRUE)
\r
429 ctns->adaptor ->free (ctns->adaptor);
\r
431 if (ctns->nodeStack != NULL)
\r
433 ctns->nodeStack->free(ctns->nodeStack);
\r
436 ANTLR3_FREE(ctns->INVALID_NODE.token);
\r
437 ANTLR3_FREE(ctns->EOF_NODE.token);
\r
438 ANTLR3_FREE(ctns->DOWN.token);
\r
439 ANTLR3_FREE(ctns->UP.token);
\r
442 if (ctns->nodes != NULL)
\r
444 ctns->nodes ->free (ctns->nodes);
\r
446 ctns->tnstream->istream ->free (ctns->tnstream->istream);
\r
447 ctns->tnstream ->free (ctns->tnstream);
\r
453 // ------------------------------------------------------------------------------
\r
457 /// Walk and fill the tree node buffer from the root tree
\r
460 fillBufferRoot(pANTLR3_COMMON_TREE_NODE_STREAM ctns)
\r
462 // Call the generic buffer routine with the root as the
\r
465 fillBuffer(ctns, ctns->root);
\r
466 ctns->p = 0; // Indicate we are at buffer start
\r
469 /// Walk tree with depth-first-search and fill nodes buffer.
\r
470 /// Don't add in DOWN, UP nodes if the supplied tree is a list (t is isNilNode)
\r
471 // such as the root tree is.
\r
474 fillBuffer(pANTLR3_COMMON_TREE_NODE_STREAM ctns, pANTLR3_BASE_TREE t)
\r
476 ANTLR3_BOOLEAN nilNode;
\r
477 ANTLR3_UINT32 nCount;
\r
480 nilNode = ctns->adaptor->isNilNode(ctns->adaptor, t);
\r
482 // If the supplied node is not a nil (list) node then we
\r
483 // add in the node itself to the vector
\r
485 if (nilNode == ANTLR3_FALSE)
\r
487 ctns->nodes->add(ctns->nodes, t, NULL);
\r
490 // Only add a DOWN node if the tree is not a nil tree and
\r
491 // the tree does have children.
\r
493 nCount = t->getChildCount(t);
\r
495 if (nilNode == ANTLR3_FALSE && nCount>0)
\r
497 ctns->addNavigationNode(ctns, ANTLR3_TOKEN_DOWN);
\r
500 // We always add any children the tree contains, which is
\r
501 // a recursive call to this function, which will cause similar
\r
502 // recursion and implement a depth first addition
\r
504 for (c = 0; c < nCount; c++)
\r
506 fillBuffer(ctns, ctns->adaptor->getChild(ctns->adaptor, t, c));
\r
509 // If the tree had children and was not a nil (list) node, then we
\r
510 // we need to add an UP node here to match the DOWN node
\r
512 if (nilNode == ANTLR3_FALSE && nCount > 0)
\r
514 ctns->addNavigationNode(ctns, ANTLR3_TOKEN_UP);
\r
519 // ------------------------------------------------------------------------------
\r
520 // Interface functions
\r
523 /// Reset the input stream to the start of the input nodes.
\r
526 reset (pANTLR3_COMMON_TREE_NODE_STREAM ctns)
\r
532 ctns->tnstream->istream->lastMarker = 0;
\r
535 // Free and reset the node stack only if this is not
\r
536 // a rewriter, which is going to reuse the originating
\r
537 // node streams node stack
\r
539 if (ctns->isRewriter != ANTLR3_TRUE)
\r
541 if (ctns->nodeStack != NULL)
\r
543 ctns->nodeStack->free(ctns->nodeStack);
\r
544 ctns->nodeStack = antlr3StackNew(INITIAL_CALL_STACK_SIZE);
\r
550 static pANTLR3_BASE_TREE
\r
551 LB(pANTLR3_TREE_NODE_STREAM tns, ANTLR3_INT32 k)
\r
555 return &(tns->ctns->INVALID_NODE.baseTree);
\r
558 if ( (tns->ctns->p - k) < 0)
\r
560 return &(tns->ctns->INVALID_NODE.baseTree);
\r
563 return tns->ctns->nodes->get(tns->ctns->nodes, tns->ctns->p - k);
\r
566 /// Get tree node at current input pointer + i ahead where i=1 is next node.
\r
567 /// i<0 indicates nodes in the past. So -1 is previous node and -2 is
\r
568 /// two nodes ago. LT(0) is undefined. For i>=n, return null.
\r
569 /// Return null for LT(0) and any index that results in an absolute address
\r
570 /// that is negative.
\r
572 /// This is analogous to the _LT() method of the TokenStream, but this
\r
573 /// returns a tree node instead of a token. Makes code gen identical
\r
574 /// for both parser and tree grammars. :)
\r
576 static pANTLR3_BASE_TREE
\r
577 _LT (pANTLR3_TREE_NODE_STREAM tns, ANTLR3_INT32 k)
\r
579 if (tns->ctns->p == -1)
\r
581 fillBufferRoot(tns->ctns);
\r
586 return LB(tns, -k);
\r
590 return &(tns->ctns->INVALID_NODE.baseTree);
\r
593 // k was a legitimate request,
\r
595 if (( tns->ctns->p + k - 1) >= (ANTLR3_INT32)(tns->ctns->nodes->count))
\r
597 return &(tns->ctns->EOF_NODE.baseTree);
\r
600 return tns->ctns->nodes->get(tns->ctns->nodes, tns->ctns->p + k - 1);
\r
603 /// Where is this stream pulling nodes from? This is not the name, but
\r
604 /// the object that provides node objects.
\r
606 static pANTLR3_BASE_TREE
\r
607 getTreeSource (pANTLR3_TREE_NODE_STREAM tns)
\r
609 return tns->ctns->root;
\r
612 /// Consume the next node from the input stream
\r
615 consume (pANTLR3_INT_STREAM is)
\r
617 pANTLR3_TREE_NODE_STREAM tns;
\r
618 pANTLR3_COMMON_TREE_NODE_STREAM ctns;
\r
620 tns = (pANTLR3_TREE_NODE_STREAM)(is->super);
\r
625 fillBufferRoot(ctns);
\r
630 static ANTLR3_UINT32
\r
631 _LA (pANTLR3_INT_STREAM is, ANTLR3_INT32 i)
\r
633 pANTLR3_TREE_NODE_STREAM tns;
\r
634 pANTLR3_BASE_TREE t;
\r
636 tns = (pANTLR3_TREE_NODE_STREAM)(is->super);
\r
638 // Ask LT for the 'token' at that position
\r
640 t = tns->_LT(tns, i);
\r
644 return ANTLR3_TOKEN_INVALID;
\r
647 // Token node was there so return the type of it
\r
649 return t->getType(t);
\r
652 /// Mark the state of the input stream so that we can come back to it
\r
653 /// after a syntactic predicate and so on.
\r
655 static ANTLR3_MARKER
\r
656 mark (pANTLR3_INT_STREAM is)
\r
658 pANTLR3_TREE_NODE_STREAM tns;
\r
659 pANTLR3_COMMON_TREE_NODE_STREAM ctns;
\r
661 tns = (pANTLR3_TREE_NODE_STREAM)(is->super);
\r
664 if (tns->ctns->p == -1)
\r
666 fillBufferRoot(tns->ctns);
\r
669 // Return the current mark point
\r
671 ctns->tnstream->istream->lastMarker = ctns->tnstream->istream->index(ctns->tnstream->istream);
\r
673 return ctns->tnstream->istream->lastMarker;
\r
677 release (pANTLR3_INT_STREAM is, ANTLR3_MARKER marker)
\r
681 /// Rewind the current state of the tree walk to the state it
\r
682 /// was in when mark() was called and it returned marker. Also,
\r
683 /// wipe out the lookahead which will force reloading a few nodes
\r
684 /// but it is better than making a copy of the lookahead buffer
\r
688 rewindMark (pANTLR3_INT_STREAM is, ANTLR3_MARKER marker)
\r
690 is->seek(is, marker);
\r
694 rewindLast (pANTLR3_INT_STREAM is)
\r
696 is->seek(is, is->lastMarker);
\r
699 /// consume() ahead until we hit index. Can't just jump ahead--must
\r
700 /// spit out the navigation nodes.
\r
703 seek (pANTLR3_INT_STREAM is, ANTLR3_MARKER index)
\r
705 pANTLR3_TREE_NODE_STREAM tns;
\r
706 pANTLR3_COMMON_TREE_NODE_STREAM ctns;
\r
708 tns = (pANTLR3_TREE_NODE_STREAM)(is->super);
\r
711 ctns->p = ANTLR3_UINT32_CAST(index);
\r
714 static ANTLR3_MARKER
\r
715 tindex (pANTLR3_INT_STREAM is)
\r
717 pANTLR3_TREE_NODE_STREAM tns;
\r
718 pANTLR3_COMMON_TREE_NODE_STREAM ctns;
\r
720 tns = (pANTLR3_TREE_NODE_STREAM)(is->super);
\r
723 return (ANTLR3_MARKER)(ctns->p);
\r
726 /// Expensive to compute the size of the whole tree while parsing.
\r
727 /// This method only returns how much input has been seen so far. So
\r
728 /// after parsing it returns true size.
\r
730 static ANTLR3_UINT32
\r
731 size (pANTLR3_INT_STREAM is)
\r
733 pANTLR3_TREE_NODE_STREAM tns;
\r
734 pANTLR3_COMMON_TREE_NODE_STREAM ctns;
\r
736 tns = (pANTLR3_TREE_NODE_STREAM)(is->super);
\r
741 fillBufferRoot(ctns);
\r
744 return ctns->nodes->size(ctns->nodes);
\r
747 /// As we flatten the tree, we use UP, DOWN nodes to represent
\r
748 /// the tree structure. When debugging we need unique nodes
\r
749 /// so instantiate new ones when uniqueNavigationNodes is true.
\r
752 addNavigationNode (pANTLR3_COMMON_TREE_NODE_STREAM ctns, ANTLR3_UINT32 ttype)
\r
754 pANTLR3_BASE_TREE node;
\r
758 if (ttype == ANTLR3_TOKEN_DOWN)
\r
760 if (ctns->hasUniqueNavigationNodes(ctns) == ANTLR3_TRUE)
\r
762 node = ctns->newDownNode(ctns);
\r
766 node = &(ctns->DOWN.baseTree);
\r
771 if (ctns->hasUniqueNavigationNodes(ctns) == ANTLR3_TRUE)
\r
773 node = ctns->newUpNode(ctns);
\r
777 node = &(ctns->UP.baseTree);
\r
781 // Now add the node we decided upon.
\r
783 ctns->nodes->add(ctns->nodes, node, NULL);
\r
787 static pANTLR3_BASE_TREE_ADAPTOR
\r
788 getTreeAdaptor (pANTLR3_TREE_NODE_STREAM tns)
\r
790 return tns->ctns->adaptor;
\r
793 static ANTLR3_BOOLEAN
\r
794 hasUniqueNavigationNodes (pANTLR3_COMMON_TREE_NODE_STREAM ctns)
\r
796 return ctns->uniqueNavigationNodes;
\r
800 setUniqueNavigationNodes (pANTLR3_TREE_NODE_STREAM tns, ANTLR3_BOOLEAN uniqueNavigationNodes)
\r
802 tns->ctns->uniqueNavigationNodes = uniqueNavigationNodes;
\r
806 /// Print out the entire tree including DOWN/UP nodes. Uses
\r
807 /// a recursive walk. Mostly useful for testing as it yields
\r
808 /// the token types not text.
\r
810 static pANTLR3_STRING
\r
811 toString (pANTLR3_TREE_NODE_STREAM tns)
\r
814 return tns->toStringSS(tns, tns->ctns->root, NULL);
\r
817 static pANTLR3_STRING
\r
818 toStringSS (pANTLR3_TREE_NODE_STREAM tns, pANTLR3_BASE_TREE start, pANTLR3_BASE_TREE stop)
\r
820 pANTLR3_STRING buf;
\r
822 buf = tns->ctns->stringFactory->newRaw(tns->ctns->stringFactory);
\r
824 tns->toStringWork(tns, start, stop, buf);
\r
830 toStringWork (pANTLR3_TREE_NODE_STREAM tns, pANTLR3_BASE_TREE p, pANTLR3_BASE_TREE stop, pANTLR3_STRING buf)
\r
836 if (!p->isNilNode(p) )
\r
838 pANTLR3_STRING text;
\r
840 text = p->toString(p);
\r
844 text = tns->ctns->stringFactory->newRaw(tns->ctns->stringFactory);
\r
846 text->addc (text, ' ');
\r
847 text->addi (text, p->getType(p));
\r
850 buf->appendS(buf, text);
\r
855 return; /* Finished */
\r
858 n = p->getChildCount(p);
\r
860 if (n > 0 && ! p->isNilNode(p) )
\r
862 buf->addc (buf, ' ');
\r
863 buf->addi (buf, ANTLR3_TOKEN_DOWN);
\r
866 for (c = 0; c<n ; c++)
\r
868 pANTLR3_BASE_TREE child;
\r
870 child = p->getChild(p, c);
\r
871 tns->toStringWork(tns, child, stop, buf);
\r
874 if (n > 0 && ! p->isNilNode(p) )
\r
876 buf->addc (buf, ' ');
\r
877 buf->addi (buf, ANTLR3_TOKEN_UP);
\r
881 static ANTLR3_UINT32
\r
882 getLookaheadSize (pANTLR3_COMMON_TREE_NODE_STREAM ctns)
\r
884 return ctns->tail < ctns->head
\r
885 ? (ctns->lookAheadLength - ctns->head + ctns->tail)
\r
886 : (ctns->tail - ctns->head);
\r
889 static pANTLR3_BASE_TREE
\r
890 newDownNode (pANTLR3_COMMON_TREE_NODE_STREAM ctns)
\r
892 pANTLR3_COMMON_TREE dNode;
\r
893 pANTLR3_COMMON_TOKEN token;
\r
895 token = antlr3CommonTokenNew(ANTLR3_TOKEN_DOWN);
\r
896 token->textState = ANTLR3_TEXT_CHARP;
\r
897 token->tokText.chars = (pANTLR3_UCHAR)"DOWN";
\r
898 dNode = antlr3CommonTreeNewFromToken(token);
\r
900 return &(dNode->baseTree);
\r
903 static pANTLR3_BASE_TREE
\r
904 newUpNode (pANTLR3_COMMON_TREE_NODE_STREAM ctns)
\r
906 pANTLR3_COMMON_TREE uNode;
\r
907 pANTLR3_COMMON_TOKEN token;
\r
909 token = antlr3CommonTokenNew(ANTLR3_TOKEN_UP);
\r
910 token->textState = ANTLR3_TEXT_CHARP;
\r
911 token->tokText.chars = (pANTLR3_UCHAR)"UP";
\r
912 uNode = antlr3CommonTreeNewFromToken(token);
\r
914 return &(uNode->baseTree);
\r
917 /// Replace from start to stop child index of parent with t, which might
\r
918 /// be a list. Number of children may be different
\r
919 /// after this call. The stream is notified because it is walking the
\r
920 /// tree and might need to know you are monkey-ing with the underlying
\r
921 /// tree. Also, it might be able to modify the node stream to avoid
\r
922 /// re-streaming for future phases.
\r
924 /// If parent is null, don't do anything; must be at root of overall tree.
\r
925 /// Can't replace whatever points to the parent externally. Do nothing.
\r
928 replaceChildren (pANTLR3_TREE_NODE_STREAM tns, pANTLR3_BASE_TREE parent, ANTLR3_INT32 startChildIndex, ANTLR3_INT32 stopChildIndex, pANTLR3_BASE_TREE t)
\r
930 if (parent != NULL)
\r
932 pANTLR3_BASE_TREE_ADAPTOR adaptor;
\r
933 pANTLR3_COMMON_TREE_ADAPTOR cta;
\r
935 adaptor = tns->getTreeAdaptor(tns);
\r
936 cta = (pANTLR3_COMMON_TREE_ADAPTOR)(adaptor->super);
\r
938 adaptor->replaceChildren(adaptor, parent, startChildIndex, stopChildIndex, t);
\r
942 static pANTLR3_BASE_TREE
\r
943 get (pANTLR3_TREE_NODE_STREAM tns, ANTLR3_INT32 k)
\r
945 if (tns->ctns->p == -1)
\r
947 fillBufferRoot(tns->ctns);
\r
950 return tns->ctns->nodes->get(tns->ctns->nodes, k);
\r
954 push (pANTLR3_COMMON_TREE_NODE_STREAM ctns, ANTLR3_INT32 index)
\r
956 ctns->nodeStack->push(ctns->nodeStack, ANTLR3_FUNC_PTR(ctns->p), NULL); // Save current index
\r
957 ctns->tnstream->istream->seek(ctns->tnstream->istream, index);
\r
960 static ANTLR3_INT32
\r
961 pop (pANTLR3_COMMON_TREE_NODE_STREAM ctns)
\r
963 ANTLR3_INT32 retVal;
\r
965 retVal = ANTLR3_UINT32_CAST(ctns->nodeStack->pop(ctns->nodeStack));
\r
966 ctns->tnstream->istream->seek(ctns->tnstream->istream, retVal);
\r