]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.databoard/cpp/DataBoardTest/libantlr3c-3.2/src/antlr3commontreenodestream.c
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.databoard / cpp / DataBoardTest / libantlr3c-3.2 / src / antlr3commontreenodestream.c
1 /// \file\r
2 /// Defines the implementation of the common node stream the default\r
3 /// tree node stream used by ANTLR.\r
4 ///\r
5 \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
10 //\r
11 // All rights reserved.\r
12 //\r
13 // Redistribution and use in source and binary forms, with or without\r
14 // modification, are permitted provided that the following conditions\r
15 // are met:\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
23 //\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
34 \r
35 #include    <antlr3commontreenodestream.h>\r
36 \r
37 #ifdef  ANTLR3_WINDOWS\r
38 #pragma warning( disable : 4100 )\r
39 #endif\r
40 \r
41 // COMMON TREE STREAM API\r
42 //\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
53 //\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
63 \r
64 // INT STREAM API\r
65 //\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
75 \r
76 \r
77 // Helper functions\r
78 //\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
81 \r
82 // Constructors\r
83 //\r
84 static  void                                            antlr3TreeNodeStreamFree                        (pANTLR3_TREE_NODE_STREAM tns);\r
85 static  void                                            antlr3CommonTreeNodeStreamFree          (pANTLR3_COMMON_TREE_NODE_STREAM ctns);\r
86 \r
87 ANTLR3_API pANTLR3_TREE_NODE_STREAM\r
88 antlr3TreeNodeStreamNew()\r
89 {\r
90     pANTLR3_TREE_NODE_STREAM stream;\r
91 \r
92     // Memory for the interface structure\r
93     //\r
94     stream  = (pANTLR3_TREE_NODE_STREAM) ANTLR3_CALLOC(1, sizeof(ANTLR3_TREE_NODE_STREAM));\r
95 \r
96     if  (stream == NULL)\r
97     {\r
98                 return  NULL;\r
99     }\r
100 \r
101     // Install basic API \r
102     //\r
103         stream->replaceChildren = replaceChildren;\r
104     stream->free                        = antlr3TreeNodeStreamFree;\r
105     \r
106     return stream;\r
107 }\r
108 \r
109 static void\r
110 antlr3TreeNodeStreamFree(pANTLR3_TREE_NODE_STREAM stream)\r
111 {   \r
112     ANTLR3_FREE(stream);\r
113 }\r
114 \r
115 ANTLR3_API pANTLR3_COMMON_TREE_NODE_STREAM\r
116 antlr3CommonTreeNodeStreamNewTree(pANTLR3_BASE_TREE tree, ANTLR3_UINT32 hint)\r
117 {\r
118         pANTLR3_COMMON_TREE_NODE_STREAM stream;\r
119 \r
120         stream = antlr3CommonTreeNodeStreamNew(tree->strFactory, hint);\r
121 \r
122         if      (stream == NULL)\r
123         {\r
124                 return  NULL;\r
125         }\r
126         stream->root    = tree;\r
127 \r
128         return stream;\r
129 }\r
130 \r
131 ANTLR3_API pANTLR3_COMMON_TREE_NODE_STREAM\r
132 antlr3CommonTreeNodeStreamNewStream(pANTLR3_COMMON_TREE_NODE_STREAM inStream)\r
133 {\r
134         pANTLR3_COMMON_TREE_NODE_STREAM stream;\r
135 \r
136         // Memory for the interface structure\r
137         //\r
138         stream  = (pANTLR3_COMMON_TREE_NODE_STREAM) ANTLR3_CALLOC(1, sizeof(ANTLR3_COMMON_TREE_NODE_STREAM));\r
139 \r
140         if      (stream == NULL)\r
141         {\r
142                 return  NULL;\r
143         }\r
144 \r
145         // Copy in all the reusable parts of the originating stream and create new\r
146         // pieces where necessary.\r
147         //\r
148 \r
149         // String factory for tree walker\r
150         //\r
151         stream->stringFactory           = inStream->stringFactory;\r
152 \r
153         // Create an adaptor for the common tree node stream\r
154         //\r
155         stream->adaptor                         = inStream->adaptor;\r
156 \r
157         // Create space for the tree node stream interface\r
158         //\r
159         stream->tnstream            = antlr3TreeNodeStreamNew();\r
160 \r
161         if      (stream->tnstream == NULL)\r
162         {\r
163                 stream->free                            (stream);\r
164 \r
165                 return  NULL;\r
166         }\r
167 \r
168         // Create space for the INT_STREAM interface\r
169         //\r
170         stream->tnstream->istream                   =  antlr3IntStreamNew();\r
171 \r
172         if      (stream->tnstream->istream == NULL)\r
173         {\r
174                 stream->tnstream->free          (stream->tnstream);\r
175                 stream->free                            (stream);\r
176 \r
177                 return  NULL;\r
178         }\r
179 \r
180         // Install the common tree node stream API\r
181         //\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
188         stream->pop                                                     =  pop;\r
189         stream->getLookaheadSize                        =  getLookaheadSize;\r
190 \r
191         stream->free                        =  antlr3CommonTreeNodeStreamFree;\r
192 \r
193         // Install the tree node stream API\r
194         //\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
203 \r
204         // Install INT_STREAM interface\r
205         //\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
215 \r
216         // Initialize data elements of INT stream\r
217         //\r
218         stream->tnstream->istream->type                 = ANTLR3_COMMONTREENODE;\r
219         stream->tnstream->istream->super            =  (stream->tnstream);\r
220 \r
221         // Initialize data elements of TREE stream\r
222         //\r
223         stream->tnstream->ctns =  stream;\r
224 \r
225         // Initialize data elements of the COMMON TREE NODE stream\r
226         //\r
227         stream->super                                   = NULL;\r
228         stream->uniqueNavigationNodes   = ANTLR3_FALSE;\r
229         stream->markers                                 = NULL;\r
230         stream->nodeStack                               = inStream->nodeStack;\r
231 \r
232         // Create the node list map\r
233         //\r
234         stream->nodes   = antlr3VectorNew(DEFAULT_INITIAL_BUFFER_SIZE);\r
235         stream->p               = -1;\r
236 \r
237         // Install the navigation nodes     \r
238         //\r
239         \r
240         // Install the navigation nodes     \r
241         //\r
242         antlr3SetCTAPI(&(stream->UP));\r
243         antlr3SetCTAPI(&(stream->DOWN));\r
244         antlr3SetCTAPI(&(stream->EOF_NODE));\r
245         antlr3SetCTAPI(&(stream->INVALID_NODE));\r
246 \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
255 \r
256         // Reuse the root tree of the originating stream\r
257         //\r
258         stream->root            = inStream->root;\r
259 \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
264         //\r
265         stream->isRewriter      = ANTLR3_TRUE;\r
266         return stream;\r
267 }\r
268 \r
269 ANTLR3_API pANTLR3_COMMON_TREE_NODE_STREAM\r
270 antlr3CommonTreeNodeStreamNew(pANTLR3_STRING_FACTORY strFactory, ANTLR3_UINT32 hint)\r
271 {\r
272         pANTLR3_COMMON_TREE_NODE_STREAM stream;\r
273         pANTLR3_COMMON_TOKEN                    token;\r
274 \r
275         // Memory for the interface structure\r
276         //\r
277         stream  = (pANTLR3_COMMON_TREE_NODE_STREAM) ANTLR3_CALLOC(1, sizeof(ANTLR3_COMMON_TREE_NODE_STREAM));\r
278 \r
279         if      (stream == NULL)\r
280         {\r
281                 return  NULL;\r
282         }\r
283 \r
284         // String factory for tree walker\r
285         //\r
286         stream->stringFactory           = strFactory;\r
287 \r
288         // Create an adaptor for the common tree node stream\r
289         //\r
290         stream->adaptor                         = ANTLR3_TREE_ADAPTORNew(strFactory);\r
291 \r
292         if      (stream->adaptor == NULL)\r
293         {\r
294                 stream->free(stream);\r
295                 return  NULL;\r
296         }\r
297 \r
298         // Create space for the tree node stream interface\r
299         //\r
300         stream->tnstream            = antlr3TreeNodeStreamNew();\r
301 \r
302         if      (stream->tnstream == NULL)\r
303         {\r
304                 stream->adaptor->free           (stream->adaptor);\r
305                 stream->free                            (stream);\r
306 \r
307                 return  NULL;\r
308         }\r
309 \r
310         // Create space for the INT_STREAM interface\r
311         //\r
312         stream->tnstream->istream                   =  antlr3IntStreamNew();\r
313 \r
314         if      (stream->tnstream->istream == NULL)\r
315         {\r
316                 stream->adaptor->free           (stream->adaptor);\r
317                 stream->tnstream->free          (stream->tnstream);\r
318                 stream->free                            (stream);\r
319 \r
320                 return  NULL;\r
321         }\r
322 \r
323         // Install the common tree node stream API\r
324         //\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
331         stream->pop                                                     =  pop;\r
332 \r
333         stream->free                        =  antlr3CommonTreeNodeStreamFree;\r
334 \r
335         // Install the tree node stream API\r
336         //\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
345 \r
346         // Install INT_STREAM interface\r
347         //\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
357 \r
358         // Initialize data elements of INT stream\r
359         //\r
360         stream->tnstream->istream->type                 = ANTLR3_COMMONTREENODE;\r
361         stream->tnstream->istream->super            =  (stream->tnstream);\r
362 \r
363         // Initialize data elements of TREE stream\r
364         //\r
365         stream->tnstream->ctns =  stream;\r
366 \r
367         // Initialize data elements of the COMMON TREE NODE stream\r
368         //\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
373 \r
374         // Create the node list map\r
375         //\r
376         if      (hint == 0)\r
377         {\r
378                 hint = DEFAULT_INITIAL_BUFFER_SIZE;\r
379         }\r
380         stream->nodes   = antlr3VectorNew(hint);\r
381         stream->p               = -1;\r
382 \r
383         // Install the navigation nodes     \r
384         //\r
385         antlr3SetCTAPI(&(stream->UP));\r
386         antlr3SetCTAPI(&(stream->DOWN));\r
387         antlr3SetCTAPI(&(stream->EOF_NODE));\r
388         antlr3SetCTAPI(&(stream->INVALID_NODE));\r
389 \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
395 \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
401 \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
407 \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
413 \r
414 \r
415         return  stream;\r
416 }\r
417 \r
418 /// Free up any resources that belong to this common tree node stream.\r
419 ///\r
420 static  void                        antlr3CommonTreeNodeStreamFree  (pANTLR3_COMMON_TREE_NODE_STREAM ctns)\r
421 {\r
422 \r
423         // If this is a rewrting stream, then certain resources\r
424         // belong to the originating node stream and we do not\r
425         // free them here.\r
426         //\r
427         if      (ctns->isRewriter != ANTLR3_TRUE)\r
428         {\r
429                 ctns->adaptor                   ->free  (ctns->adaptor);\r
430 \r
431                 if      (ctns->nodeStack != NULL)\r
432                 {\r
433                         ctns->nodeStack->free(ctns->nodeStack);\r
434                 }\r
435 \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
440         }\r
441         \r
442         if      (ctns->nodes != NULL)\r
443         {\r
444                 ctns->nodes                     ->free  (ctns->nodes);\r
445         }\r
446         ctns->tnstream->istream ->free  (ctns->tnstream->istream);\r
447     ctns->tnstream                      ->free  (ctns->tnstream);\r
448 \r
449 \r
450     ANTLR3_FREE(ctns);\r
451 }\r
452 \r
453 // ------------------------------------------------------------------------------\r
454 // Local helpers\r
455 //\r
456 \r
457 /// Walk and fill the tree node buffer from the root tree\r
458 ///\r
459 static void\r
460 fillBufferRoot(pANTLR3_COMMON_TREE_NODE_STREAM ctns)\r
461 {\r
462         // Call the generic buffer routine with the root as the\r
463         // argument\r
464         //\r
465         fillBuffer(ctns, ctns->root);\r
466         ctns->p = 0;                                    // Indicate we are at buffer start\r
467 }\r
468 \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
472 ///\r
473 static void\r
474 fillBuffer(pANTLR3_COMMON_TREE_NODE_STREAM ctns, pANTLR3_BASE_TREE t)\r
475 {\r
476         ANTLR3_BOOLEAN  nilNode;\r
477         ANTLR3_UINT32   nCount;\r
478         ANTLR3_UINT32   c;\r
479 \r
480         nilNode = ctns->adaptor->isNilNode(ctns->adaptor, t);\r
481 \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
484         //\r
485         if      (nilNode == ANTLR3_FALSE)\r
486         {\r
487                 ctns->nodes->add(ctns->nodes, t, NULL); \r
488         }\r
489 \r
490         // Only add a DOWN node if the tree is not a nil tree and\r
491         // the tree does have children.\r
492         //\r
493         nCount = t->getChildCount(t);\r
494 \r
495         if      (nilNode == ANTLR3_FALSE && nCount>0)\r
496         {\r
497                 ctns->addNavigationNode(ctns, ANTLR3_TOKEN_DOWN);\r
498         }\r
499 \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
503         //\r
504         for     (c = 0; c < nCount; c++)\r
505         {\r
506                 fillBuffer(ctns, ctns->adaptor->getChild(ctns->adaptor, t, c));\r
507         }\r
508 \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
511         //\r
512         if      (nilNode == ANTLR3_FALSE && nCount > 0)\r
513         {\r
514                 ctns->addNavigationNode(ctns, ANTLR3_TOKEN_UP);\r
515         }\r
516 }\r
517 \r
518 \r
519 // ------------------------------------------------------------------------------\r
520 // Interface functions\r
521 //\r
522 \r
523 /// Reset the input stream to the start of the input nodes.\r
524 ///\r
525 static  void            \r
526 reset       (pANTLR3_COMMON_TREE_NODE_STREAM ctns)\r
527 {\r
528         if      (ctns->p != -1)\r
529         {\r
530                 ctns->p                                                                 = 0;\r
531         }\r
532         ctns->tnstream->istream->lastMarker             = 0;\r
533 \r
534 \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
538         //\r
539         if  (ctns->isRewriter != ANTLR3_TRUE)\r
540     {\r
541                 if      (ctns->nodeStack != NULL)\r
542                 {\r
543                         ctns->nodeStack->free(ctns->nodeStack);\r
544                         ctns->nodeStack = antlr3StackNew(INITIAL_CALL_STACK_SIZE);\r
545                 }\r
546         }\r
547 }\r
548 \r
549 \r
550 static pANTLR3_BASE_TREE\r
551 LB(pANTLR3_TREE_NODE_STREAM tns, ANTLR3_INT32 k)\r
552 {\r
553         if      ( k==0)\r
554         {\r
555                 return  &(tns->ctns->INVALID_NODE.baseTree);\r
556         }\r
557 \r
558         if      ( (tns->ctns->p - k) < 0)\r
559         {\r
560                 return  &(tns->ctns->INVALID_NODE.baseTree);\r
561         }\r
562 \r
563         return tns->ctns->nodes->get(tns->ctns->nodes, tns->ctns->p - k);\r
564 }\r
565 \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
571 ///\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
575 ///\r
576 static  pANTLR3_BASE_TREE           \r
577 _LT         (pANTLR3_TREE_NODE_STREAM tns, ANTLR3_INT32 k)\r
578 {\r
579         if      (tns->ctns->p == -1)\r
580         {\r
581                 fillBufferRoot(tns->ctns);\r
582         }\r
583 \r
584         if      (k < 0)\r
585         {\r
586                 return LB(tns, -k);\r
587         }\r
588         else if (k == 0)\r
589         {\r
590                 return  &(tns->ctns->INVALID_NODE.baseTree);\r
591         }\r
592 \r
593         // k was a legitimate request, \r
594         //\r
595         if      (( tns->ctns->p + k - 1) >= (ANTLR3_INT32)(tns->ctns->nodes->count))\r
596         {\r
597                 return &(tns->ctns->EOF_NODE.baseTree);\r
598         }\r
599 \r
600         return  tns->ctns->nodes->get(tns->ctns->nodes, tns->ctns->p + k - 1);\r
601 }\r
602 \r
603 /// Where is this stream pulling nodes from?  This is not the name, but\r
604 /// the object that provides node objects.\r
605 ///\r
606 static  pANTLR3_BASE_TREE           \r
607 getTreeSource   (pANTLR3_TREE_NODE_STREAM tns)\r
608 {\r
609     return  tns->ctns->root;\r
610 }\r
611 \r
612 /// Consume the next node from the input stream\r
613 ///\r
614 static  void                \r
615 consume (pANTLR3_INT_STREAM is)\r
616 {\r
617     pANTLR3_TREE_NODE_STREAM            tns;\r
618     pANTLR3_COMMON_TREE_NODE_STREAM     ctns;\r
619 \r
620     tns     = (pANTLR3_TREE_NODE_STREAM)(is->super);\r
621     ctns    = tns->ctns;\r
622 \r
623         if      (ctns->p == -1)\r
624         {\r
625                 fillBufferRoot(ctns);\r
626         }\r
627         ctns->p++;\r
628 }\r
629 \r
630 static  ANTLR3_UINT32       \r
631 _LA         (pANTLR3_INT_STREAM is, ANTLR3_INT32 i)\r
632 {\r
633         pANTLR3_TREE_NODE_STREAM                tns;\r
634         pANTLR3_BASE_TREE                               t;\r
635 \r
636         tns         = (pANTLR3_TREE_NODE_STREAM)(is->super);\r
637 \r
638         // Ask LT for the 'token' at that position\r
639         //\r
640         t = tns->_LT(tns, i);\r
641 \r
642         if      (t == NULL)\r
643         {\r
644                 return  ANTLR3_TOKEN_INVALID;\r
645         }\r
646 \r
647         // Token node was there so return the type of it\r
648         //\r
649         return  t->getType(t);\r
650 }\r
651 \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
654 ///\r
655 static  ANTLR3_MARKER       \r
656 mark    (pANTLR3_INT_STREAM is)\r
657 {\r
658         pANTLR3_TREE_NODE_STREAM                tns;\r
659         pANTLR3_COMMON_TREE_NODE_STREAM ctns;\r
660 \r
661         tns         = (pANTLR3_TREE_NODE_STREAM)(is->super);\r
662         ctns    = tns->ctns;\r
663 \r
664         if      (tns->ctns->p == -1)\r
665         {\r
666                 fillBufferRoot(tns->ctns);\r
667         }\r
668 \r
669         // Return the current mark point\r
670         //\r
671         ctns->tnstream->istream->lastMarker = ctns->tnstream->istream->index(ctns->tnstream->istream);\r
672 \r
673         return ctns->tnstream->istream->lastMarker;\r
674 }\r
675 \r
676 static  void                \r
677 release (pANTLR3_INT_STREAM is, ANTLR3_MARKER marker)\r
678 {\r
679 }\r
680 \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
685 /// upon mark().\r
686 ///\r
687 static  void                \r
688 rewindMark          (pANTLR3_INT_STREAM is, ANTLR3_MARKER marker)\r
689 {\r
690         is->seek(is, marker);\r
691 }\r
692 \r
693 static  void                \r
694 rewindLast      (pANTLR3_INT_STREAM is)\r
695 {\r
696    is->seek(is, is->lastMarker);\r
697 }\r
698 \r
699 /// consume() ahead until we hit index.  Can't just jump ahead--must\r
700 /// spit out the navigation nodes.\r
701 ///\r
702 static  void                \r
703 seek    (pANTLR3_INT_STREAM is, ANTLR3_MARKER index)\r
704 {\r
705     pANTLR3_TREE_NODE_STREAM            tns;\r
706     pANTLR3_COMMON_TREE_NODE_STREAM     ctns;\r
707 \r
708     tns     = (pANTLR3_TREE_NODE_STREAM)(is->super);\r
709     ctns    = tns->ctns;\r
710 \r
711         ctns->p = ANTLR3_UINT32_CAST(index);\r
712 }\r
713 \r
714 static  ANTLR3_MARKER               \r
715 tindex  (pANTLR3_INT_STREAM is)\r
716 {\r
717     pANTLR3_TREE_NODE_STREAM            tns;\r
718     pANTLR3_COMMON_TREE_NODE_STREAM     ctns;\r
719 \r
720     tns     = (pANTLR3_TREE_NODE_STREAM)(is->super);\r
721     ctns    = tns->ctns;\r
722 \r
723         return (ANTLR3_MARKER)(ctns->p);\r
724 }\r
725 \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
729 ///\r
730 static  ANTLR3_UINT32               \r
731 size    (pANTLR3_INT_STREAM is)\r
732 {\r
733     pANTLR3_TREE_NODE_STREAM            tns;\r
734     pANTLR3_COMMON_TREE_NODE_STREAM     ctns;\r
735 \r
736     tns     = (pANTLR3_TREE_NODE_STREAM)(is->super);\r
737     ctns    = tns->ctns;\r
738 \r
739         if      (ctns->p == -1)\r
740         {\r
741                 fillBufferRoot(ctns);\r
742         }\r
743 \r
744         return ctns->nodes->size(ctns->nodes);\r
745 }\r
746 \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
750 ///\r
751 static  void                \r
752 addNavigationNode           (pANTLR3_COMMON_TREE_NODE_STREAM ctns, ANTLR3_UINT32 ttype)\r
753 {\r
754         pANTLR3_BASE_TREE           node;\r
755 \r
756         node = NULL;\r
757 \r
758         if      (ttype == ANTLR3_TOKEN_DOWN)\r
759         {\r
760                 if  (ctns->hasUniqueNavigationNodes(ctns) == ANTLR3_TRUE)\r
761                 {\r
762                         node    = ctns->newDownNode(ctns);\r
763                 }\r
764                 else\r
765                 {\r
766                         node    = &(ctns->DOWN.baseTree);\r
767                 }\r
768         }\r
769         else\r
770         {\r
771                 if  (ctns->hasUniqueNavigationNodes(ctns) == ANTLR3_TRUE)\r
772                 {\r
773                         node    = ctns->newUpNode(ctns);\r
774                 }\r
775                 else\r
776                 {\r
777                         node    = &(ctns->UP.baseTree);\r
778                 }\r
779         }\r
780 \r
781         // Now add the node we decided upon.\r
782         //\r
783         ctns->nodes->add(ctns->nodes, node, NULL);\r
784 }\r
785 \r
786 \r
787 static  pANTLR3_BASE_TREE_ADAPTOR                           \r
788 getTreeAdaptor  (pANTLR3_TREE_NODE_STREAM tns)\r
789 {\r
790     return  tns->ctns->adaptor;\r
791 }\r
792 \r
793 static  ANTLR3_BOOLEAN      \r
794 hasUniqueNavigationNodes            (pANTLR3_COMMON_TREE_NODE_STREAM ctns)\r
795 {\r
796     return  ctns->uniqueNavigationNodes;\r
797 }\r
798 \r
799 static  void                \r
800 setUniqueNavigationNodes            (pANTLR3_TREE_NODE_STREAM tns, ANTLR3_BOOLEAN uniqueNavigationNodes)\r
801 {\r
802     tns->ctns->uniqueNavigationNodes = uniqueNavigationNodes;\r
803 }\r
804 \r
805 \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
809 ///\r
810 static  pANTLR3_STRING      \r
811 toString            (pANTLR3_TREE_NODE_STREAM tns)\r
812 {\r
813 \r
814     return  tns->toStringSS(tns, tns->ctns->root, NULL);\r
815 }\r
816 \r
817 static  pANTLR3_STRING      \r
818 toStringSS          (pANTLR3_TREE_NODE_STREAM tns, pANTLR3_BASE_TREE start, pANTLR3_BASE_TREE stop)\r
819 {\r
820     pANTLR3_STRING  buf;\r
821 \r
822     buf = tns->ctns->stringFactory->newRaw(tns->ctns->stringFactory);\r
823 \r
824     tns->toStringWork(tns, start, stop, buf);\r
825 \r
826     return  buf;\r
827 }\r
828 \r
829 static  void        \r
830 toStringWork    (pANTLR3_TREE_NODE_STREAM tns, pANTLR3_BASE_TREE p, pANTLR3_BASE_TREE stop, pANTLR3_STRING buf)\r
831 {\r
832 \r
833         ANTLR3_UINT32   n;\r
834         ANTLR3_UINT32   c;\r
835 \r
836         if      (!p->isNilNode(p) )\r
837         {\r
838                 pANTLR3_STRING  text;\r
839 \r
840                 text    = p->toString(p);\r
841 \r
842                 if  (text == NULL)\r
843                 {\r
844                         text = tns->ctns->stringFactory->newRaw(tns->ctns->stringFactory);\r
845 \r
846                         text->addc      (text, ' ');\r
847                         text->addi      (text, p->getType(p));\r
848                 }\r
849 \r
850                 buf->appendS(buf, text);\r
851         }\r
852 \r
853         if      (p == stop)\r
854         {\r
855                 return;         /* Finished */\r
856         }\r
857 \r
858         n = p->getChildCount(p);\r
859 \r
860         if      (n > 0 && ! p->isNilNode(p) )\r
861         {\r
862                 buf->addc   (buf, ' ');\r
863                 buf->addi   (buf, ANTLR3_TOKEN_DOWN);\r
864         }\r
865 \r
866         for     (c = 0; c<n ; c++)\r
867         {\r
868                 pANTLR3_BASE_TREE   child;\r
869 \r
870                 child = p->getChild(p, c);\r
871                 tns->toStringWork(tns, child, stop, buf);\r
872         }\r
873 \r
874         if      (n > 0 && ! p->isNilNode(p) )\r
875         {\r
876                 buf->addc   (buf, ' ');\r
877                 buf->addi   (buf, ANTLR3_TOKEN_UP);\r
878         }\r
879 }\r
880 \r
881 static  ANTLR3_UINT32       \r
882 getLookaheadSize        (pANTLR3_COMMON_TREE_NODE_STREAM ctns)\r
883 {\r
884     return      ctns->tail < ctns->head \r
885             ?   (ctns->lookAheadLength - ctns->head + ctns->tail)\r
886             :   (ctns->tail - ctns->head);\r
887 }\r
888 \r
889 static  pANTLR3_BASE_TREE           \r
890 newDownNode             (pANTLR3_COMMON_TREE_NODE_STREAM ctns)\r
891 {\r
892     pANTLR3_COMMON_TREE     dNode;\r
893     pANTLR3_COMMON_TOKEN    token;\r
894 \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
899 \r
900     return  &(dNode->baseTree);\r
901 }\r
902 \r
903 static  pANTLR3_BASE_TREE           \r
904 newUpNode               (pANTLR3_COMMON_TREE_NODE_STREAM ctns)\r
905 {\r
906     pANTLR3_COMMON_TREE     uNode;\r
907     pANTLR3_COMMON_TOKEN    token;\r
908 \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
913 \r
914     return  &(uNode->baseTree);\r
915 }\r
916 \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
923 ///\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
926 ///\r
927 static  void                                            \r
928 replaceChildren                         (pANTLR3_TREE_NODE_STREAM tns, pANTLR3_BASE_TREE parent, ANTLR3_INT32 startChildIndex, ANTLR3_INT32 stopChildIndex, pANTLR3_BASE_TREE t)\r
929 {\r
930         if      (parent != NULL)\r
931         {\r
932                 pANTLR3_BASE_TREE_ADAPTOR       adaptor;\r
933                 pANTLR3_COMMON_TREE_ADAPTOR     cta;\r
934 \r
935                 adaptor = tns->getTreeAdaptor(tns);\r
936                 cta             = (pANTLR3_COMMON_TREE_ADAPTOR)(adaptor->super);\r
937 \r
938                 adaptor->replaceChildren(adaptor, parent, startChildIndex, stopChildIndex, t);\r
939         }\r
940 }\r
941 \r
942 static  pANTLR3_BASE_TREE\r
943 get                                                     (pANTLR3_TREE_NODE_STREAM tns, ANTLR3_INT32 k)\r
944 {\r
945         if      (tns->ctns->p == -1)\r
946         {\r
947                 fillBufferRoot(tns->ctns);\r
948         }\r
949 \r
950         return tns->ctns->nodes->get(tns->ctns->nodes, k);\r
951 }\r
952 \r
953 static  void\r
954 push                                            (pANTLR3_COMMON_TREE_NODE_STREAM ctns, ANTLR3_INT32 index)\r
955 {\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
958 }\r
959 \r
960 static  ANTLR3_INT32\r
961 pop                                                     (pANTLR3_COMMON_TREE_NODE_STREAM ctns)\r
962 {\r
963         ANTLR3_INT32    retVal;\r
964 \r
965         retVal = ANTLR3_UINT32_CAST(ctns->nodeStack->pop(ctns->nodeStack));\r
966         ctns->tnstream->istream->seek(ctns->tnstream->istream, retVal);\r
967         return retVal;\r
968 }\r