]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.databoard/cpp/DataBoardTest/libantlr3c-3.2/src/antlr3basetreeadaptor.c
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.databoard / cpp / DataBoardTest / libantlr3c-3.2 / src / antlr3basetreeadaptor.c
1 /** \file\r
2  * Contains the base functions that all tree adaptors start with.\r
3  * this implementation can then be overridden by any higher implementation.\r
4  * \r
5  */\r
6 \r
7 // [The "BSD licence"]\r
8 // Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC\r
9 // http://www.temporal-wave.com\r
10 // http://www.linkedin.com/in/jimidle\r
11 //\r
12 // All rights reserved.\r
13 //\r
14 // Redistribution and use in source and binary forms, with or without\r
15 // modification, are permitted provided that the following conditions\r
16 // are met:\r
17 // 1. Redistributions of source code must retain the above copyright\r
18 //    notice, this list of conditions and the following disclaimer.\r
19 // 2. Redistributions in binary form must reproduce the above copyright\r
20 //    notice, this list of conditions and the following disclaimer in the\r
21 //    documentation and/or other materials provided with the distribution.\r
22 // 3. The name of the author may not be used to endorse or promote products\r
23 //    derived from this software without specific prior written permission.\r
24 //\r
25 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\r
26 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
27 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
28 // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\r
29 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
30 // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
31 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
32 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
33 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
34 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
35 \r
36 #include    <antlr3basetreeadaptor.h>\r
37 \r
38 #ifdef  ANTLR3_WINDOWS\r
39 #pragma warning( disable : 4100 )\r
40 #endif\r
41 \r
42 /* Interface functions\r
43  */\r
44 static  pANTLR3_BASE_TREE       nilNode                                 (pANTLR3_BASE_TREE_ADAPTOR adaptor);\r
45 static  pANTLR3_BASE_TREE       dbgNil                                  (pANTLR3_BASE_TREE_ADAPTOR adaptor);\r
46 static  pANTLR3_BASE_TREE       dupTree                                 (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t);\r
47 static  pANTLR3_BASE_TREE       dbgDupTree                              (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t);\r
48 static  pANTLR3_BASE_TREE       dupTreeTT                               (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, pANTLR3_BASE_TREE parent);\r
49 static  void                            addChild                                (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, pANTLR3_BASE_TREE child);\r
50 static  void                            dbgAddChild                             (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, pANTLR3_BASE_TREE child);\r
51 static  pANTLR3_BASE_TREE       becomeRoot                              (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE newRoot, pANTLR3_BASE_TREE oldRoot);\r
52 static  pANTLR3_BASE_TREE       dbgBecomeRoot                   (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE newRoot, pANTLR3_BASE_TREE oldRoot);\r
53 static  pANTLR3_BASE_TREE       rulePostProcessing              (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE root);\r
54 static  void                            addChildToken                   (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, pANTLR3_COMMON_TOKEN child);\r
55 static  void                            dbgAddChildToken                (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, pANTLR3_COMMON_TOKEN child);\r
56 static  pANTLR3_BASE_TREE       becomeRootToken                 (pANTLR3_BASE_TREE_ADAPTOR adaptor, void * newRoot, pANTLR3_BASE_TREE oldRoot);\r
57 static  pANTLR3_BASE_TREE       dbgBecomeRootToken              (pANTLR3_BASE_TREE_ADAPTOR adaptor, void * newRoot, pANTLR3_BASE_TREE oldRoot);\r
58 static  pANTLR3_BASE_TREE       createTypeToken                 (pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_COMMON_TOKEN fromToken);\r
59 static  pANTLR3_BASE_TREE       dbgCreateTypeToken              (pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_COMMON_TOKEN fromToken);\r
60 static  pANTLR3_BASE_TREE       createTypeTokenText             (pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_COMMON_TOKEN fromToken, pANTLR3_UINT8 text);\r
61 static  pANTLR3_BASE_TREE       dbgCreateTypeTokenText  (pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_COMMON_TOKEN fromToken, pANTLR3_UINT8 text);\r
62 static  pANTLR3_BASE_TREE       createTypeText                  (pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_UINT8 text);\r
63 static  pANTLR3_BASE_TREE       dbgCreateTypeText               (pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_UINT8 text);\r
64 static  ANTLR3_UINT32           getType                                 (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t);\r
65 static  void                            setType                                 (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, ANTLR3_UINT32 type);\r
66 static  pANTLR3_STRING          getText                                 (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t);\r
67 static  void                            setText                                 (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_STRING t);\r
68 static  void                            setText8                                (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_UINT8 t);\r
69 static  pANTLR3_BASE_TREE       getChild                                (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, ANTLR3_UINT32 i);\r
70 static  ANTLR3_UINT32           getChildCount                   (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t);\r
71 static  ANTLR3_UINT32           getUniqueID                             (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t);\r
72 static  ANTLR3_BOOLEAN          isNilNode                               (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t);\r
73 static  pANTLR3_STRING          makeDot                                 (pANTLR3_BASE_TREE_ADAPTOR adaptor, void * theTree);\r
74 \r
75 /** Given a pointer to a base tree adaptor structure (which is usually embedded in the\r
76  *  super class the implements the tree adaptor used in the parse), initialize its\r
77  *  function pointers and so on.\r
78  */\r
79 ANTLR3_API void\r
80 antlr3BaseTreeAdaptorInit(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_DEBUG_EVENT_LISTENER       debugger)\r
81 {\r
82         // Initialize the interface\r
83         //\r
84         if      (debugger == NULL)\r
85         {\r
86                 adaptor->nilNode                                = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR))                                                               \r
87                                                                                                                                                                 nilNode;\r
88                 adaptor->addChild                               = (void   (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, void *))                                                               \r
89                                                                                                                                                                 addChild;\r
90                 adaptor->becomeRoot                             = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, void *))                               \r
91                                                                                                                                                                 becomeRoot;\r
92                 adaptor->addChildToken                  = (void   (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, pANTLR3_COMMON_TOKEN)) \r
93                                                                                                                                                                 addChildToken;\r
94                 adaptor->becomeRootToken                = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, void *))\r
95                                                                                                                                                                 becomeRootToken;\r
96                 adaptor->createTypeToken                = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, ANTLR3_UINT32, pANTLR3_COMMON_TOKEN))\r
97                                                                                                                                                                 createTypeToken;\r
98                 adaptor->createTypeTokenText    = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, ANTLR3_UINT32, pANTLR3_COMMON_TOKEN, pANTLR3_UINT8))\r
99                                                                                                                                                                 createTypeTokenText;\r
100                 adaptor->createTypeText                 = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, ANTLR3_UINT32, pANTLR3_UINT8))\r
101                                                                                                                                                                 createTypeText;\r
102                 adaptor->dupTree                                = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, void *))                                               \r
103                                                                                                                                                                 dupTree;\r
104         }\r
105         else\r
106         {\r
107                 adaptor->nilNode                                = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR))\r
108                                                                                 dbgNil;\r
109                 adaptor->addChild                               = (void   (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, void *))\r
110                                                                                 dbgAddChild;\r
111                 adaptor->becomeRoot                             = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, void *))\r
112                                                                                                                                                                 dbgBecomeRoot;\r
113                 adaptor->addChildToken                  = (void   (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, pANTLR3_COMMON_TOKEN))\r
114                                                                                 dbgAddChildToken;\r
115                 adaptor->becomeRootToken                = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, void *))\r
116                                                                                 dbgBecomeRootToken;\r
117                 adaptor->createTypeToken                = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, ANTLR3_UINT32, pANTLR3_COMMON_TOKEN))\r
118                                                                                 dbgCreateTypeToken;\r
119                 adaptor->createTypeTokenText    = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, ANTLR3_UINT32, pANTLR3_COMMON_TOKEN, pANTLR3_UINT8))\r
120                                                                                 dbgCreateTypeTokenText;\r
121                 adaptor->createTypeText                 = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, ANTLR3_UINT32, pANTLR3_UINT8))\r
122                                                                                 dbgCreateTypeText;\r
123                 adaptor->dupTree                                = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, void *))\r
124                                                                                 dbgDupTree;\r
125                 debugger->adaptor                               = adaptor;\r
126         }\r
127 \r
128         adaptor->dupTreeTT                              =  (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, void *))\r
129                                                                                 dupTreeTT;\r
130         adaptor->rulePostProcessing             =  (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, void *))\r
131                                                                                 rulePostProcessing;\r
132         adaptor->getType                                =  (ANTLR3_UINT32 (*)(pANTLR3_BASE_TREE_ADAPTOR, void *))\r
133                                                                                 getType;\r
134         adaptor->setType                                =  (void   (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, ANTLR3_UINT32))\r
135                                                                                                                                                                 setType;\r
136         adaptor->getText                                =  (pANTLR3_STRING (*) (pANTLR3_BASE_TREE_ADAPTOR, void *))\r
137                                                                                 getText;\r
138         adaptor->setText8                               =  (void   (*)(pANTLR3_BASE_TREE_ADAPTOR, pANTLR3_UINT8))\r
139                                                                                                                                                                 setText8;\r
140         adaptor->setText                                =  (void   (*)(pANTLR3_BASE_TREE_ADAPTOR, pANTLR3_STRING))\r
141                                                                                 setText;\r
142         adaptor->getChild                               =  (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, ANTLR3_UINT32))\r
143                                                                                 getChild;\r
144         adaptor->getChildCount                  =  (ANTLR3_UINT32 (*)(pANTLR3_BASE_TREE_ADAPTOR, void *))\r
145                                                                                 getChildCount;\r
146         adaptor->getUniqueID                    =  (ANTLR3_UINT32 (*)(pANTLR3_BASE_TREE_ADAPTOR, void *))\r
147                                                                                 getUniqueID;\r
148         adaptor->isNilNode                              =  (ANTLR3_BOOLEAN (*)(pANTLR3_BASE_TREE_ADAPTOR, void *))\r
149                                                                                 isNilNode;\r
150 \r
151         adaptor->makeDot                                =  (pANTLR3_STRING  (*)(pANTLR3_BASE_TREE_ADAPTOR, void *))\r
152                                                                                                                                                                 makeDot;\r
153         \r
154         /* Remaining functions filled in by the caller.\r
155          */\r
156         return;\r
157 }\r
158 \r
159 static void\r
160 defineDotNodes(pANTLR3_BASE_TREE_ADAPTOR adaptor, void * t, pANTLR3_STRING dotSpec )\r
161 {\r
162         // How many nodes are we talking about?\r
163         //\r
164         int     nCount;\r
165         int i;\r
166     pANTLR3_BASE_TREE child;\r
167         char    buff[64];\r
168         pANTLR3_STRING  text;\r
169         int             j;\r
170 \r
171 \r
172 \r
173 \r
174 \r
175         // Count the nodes\r
176         //\r
177         nCount = adaptor->getChildCount(adaptor, t);\r
178 \r
179         if      (nCount == 0)\r
180         {\r
181                 // This will already have been included as a child of another node\r
182                 // so there is nothing to add.\r
183                 //\r
184                 return;\r
185         }\r
186 \r
187         // For each child of the current tree, define a node using the\r
188         // memory address of the node to name it\r
189         //\r
190         for     (i = 0; i<nCount; i++)\r
191         {\r
192 \r
193                 // Pick up a pointer for the child\r
194                 //\r
195                 child = adaptor->getChild(adaptor, t, i);\r
196 \r
197                 // Name the node\r
198                 //\r
199                 sprintf(buff, "\tn%p[label=\"", child);\r
200                 dotSpec->append8(dotSpec, buff);\r
201                 text = adaptor->getText(adaptor, child);\r
202                 for (j = 0; j < (ANTLR3_INT32)(text->len); j++)\r
203                 {\r
204             switch(text->charAt(text, j))\r
205             {\r
206                 case '"':\r
207 \r
208                     dotSpec->append8(dotSpec, "\\\"");\r
209                     break;\r
210 \r
211                 case '\n':\r
212 \r
213                     dotSpec->append8(dotSpec, "\\n");\r
214                     break;\r
215 \r
216                 case '\r':\r
217 \r
218                     dotSpec->append8(dotSpec, "\\r");\r
219                     break;\r
220 \r
221                 default:\r
222 \r
223                     dotSpec->addc(dotSpec, text->charAt(text, j));\r
224                     break;\r
225             }\r
226                 }\r
227                 dotSpec->append8(dotSpec, "\"]\n");\r
228 \r
229                 // And now define the children of this child (if any)\r
230                 //\r
231                 defineDotNodes(adaptor, child, dotSpec);\r
232         }\r
233         \r
234         // Done\r
235         //\r
236         return;\r
237 }\r
238 \r
239 static void\r
240 defineDotEdges(pANTLR3_BASE_TREE_ADAPTOR adaptor, void * t, pANTLR3_STRING dotSpec)\r
241 {\r
242         // How many nodes are we talking about?\r
243         //\r
244         int     nCount;\r
245         int i;\r
246 \r
247         if      (t == NULL)\r
248         {\r
249                 // No tree, so do nothing\r
250                 //\r
251                 return;\r
252         }\r
253 \r
254         // Count the nodes\r
255         //\r
256         nCount = adaptor->getChildCount(adaptor, t);\r
257 \r
258         if      (nCount == 0)\r
259         {\r
260                 // This will already have been included as a child of another node\r
261                 // so there is nothing to add.\r
262                 //\r
263                 return;\r
264         }\r
265 \r
266         // For each child, define an edge from this parent, then process\r
267         // and children of this child in the same way\r
268         //\r
269         for     (i=0; i<nCount; i++)\r
270         {\r
271                 pANTLR3_BASE_TREE child;\r
272                 char    buff[128];\r
273         pANTLR3_STRING text;\r
274         int                 j;\r
275 \r
276                 // Next child\r
277                 //\r
278                 child   = adaptor->getChild(adaptor, t, i);\r
279 \r
280                 // Create the edge relation\r
281                 //\r
282                 sprintf(buff, "\t\tn%p -> n%p\t\t// ",  t, child);\r
283         \r
284                 dotSpec->append8(dotSpec, buff);\r
285 \r
286                 // Document the relationship\r
287                 //\r
288         text = adaptor->getText(adaptor, t);\r
289                 for (j = 0; j < (ANTLR3_INT32)(text->len); j++)\r
290         {\r
291                 switch(text->charAt(text, j))\r
292                 {\r
293                     case '"':\r
294 \r
295                         dotSpec->append8(dotSpec, "\\\"");\r
296                         break;\r
297 \r
298                     case '\n':\r
299 \r
300                         dotSpec->append8(dotSpec, "\\n");\r
301                         break;\r
302 \r
303                     case '\r':\r
304 \r
305                         dotSpec->append8(dotSpec, "\\r");\r
306                         break;\r
307 \r
308                     default:\r
309 \r
310                         dotSpec->addc(dotSpec, text->charAt(text, j));\r
311                         break;\r
312                 }\r
313         }\r
314 \r
315         dotSpec->append8(dotSpec, " -> ");\r
316 \r
317         text = adaptor->getText(adaptor, child);\r
318         for (j = 0; j < (ANTLR3_INT32)(text->len); j++)\r
319         {\r
320                 switch(text->charAt(text, j))\r
321                 {\r
322                     case '"':\r
323 \r
324                         dotSpec->append8(dotSpec, "\\\"");\r
325                         break;\r
326 \r
327                     case '\n':\r
328 \r
329                         dotSpec->append8(dotSpec, "\\n");\r
330                         break;\r
331 \r
332                     case '\r':\r
333 \r
334                         dotSpec->append8(dotSpec, "\\r");\r
335                         break;\r
336 \r
337                     default:\r
338 \r
339                         dotSpec->addc(dotSpec, text->charAt(text, j));\r
340                         break;\r
341                 }\r
342         }\r
343                 dotSpec->append8(dotSpec, "\n");\r
344 \r
345         \r
346                 // Define edges for this child\r
347                 //\r
348                 defineDotEdges(adaptor, child, dotSpec);\r
349         }\r
350 \r
351         // Done\r
352         //\r
353         return;\r
354 }\r
355 \r
356 /// Produce a DOT specification for graphviz\r
357 //\r
358 static pANTLR3_STRING\r
359 makeDot (pANTLR3_BASE_TREE_ADAPTOR adaptor, void * theTree)\r
360 {\r
361         // The string we are building up\r
362         //\r
363         pANTLR3_STRING          dotSpec;\r
364         char                buff[64];\r
365         pANTLR3_STRING      text;\r
366         int                 j;\r
367 \r
368         dotSpec = adaptor->strFactory->newStr8\r
369                 \r
370                 (\r
371                         adaptor->strFactory,\r
372 \r
373                         // Default look and feel\r
374                         //\r
375                         (pANTLR3_UINT8)\r
376                         "digraph {\n\n"\r
377                         "\tordering=out;\n"\r
378                         "\tranksep=.4;\n"\r
379                         "\tbgcolor=\"lightgrey\";  node [shape=box, fixedsize=false, fontsize=12, fontname=\"Helvetica-bold\", fontcolor=\"blue\"\n"\r
380                         "\twidth=.25, height=.25, color=\"black\", fillcolor=\"white\", style=\"filled, solid, bold\"];\n\n"\r
381                         "\tedge [arrowsize=.5, color=\"black\", style=\"bold\"]\n\n"\r
382                 );\r
383 \r
384     if  (theTree == NULL)\r
385         {\r
386                 // No tree, so create a blank spec\r
387                 //\r
388                 dotSpec->append8(dotSpec, "n0[label=\"EMPTY TREE\"]\n");\r
389                 return dotSpec;\r
390         }\r
391 \r
392     sprintf(buff, "\tn%p[label=\"", theTree);\r
393         dotSpec->append8(dotSpec, buff);\r
394     text = adaptor->getText(adaptor, theTree);\r
395     for (j = 0; j < (ANTLR3_INT32)(text->len); j++)\r
396     {\r
397             switch(text->charAt(text, j))\r
398             {\r
399                 case '"':\r
400 \r
401                     dotSpec->append8(dotSpec, "\\\"");\r
402                     break;\r
403 \r
404                 case '\n':\r
405 \r
406                     dotSpec->append8(dotSpec, "\\n");\r
407                     break;\r
408 \r
409                 case '\r':\r
410 \r
411                     dotSpec->append8(dotSpec, "\\r");\r
412                     break;\r
413 \r
414                 default:\r
415 \r
416                     dotSpec->addc(dotSpec, text->charAt(text, j));\r
417                     break;\r
418             }\r
419     }\r
420         dotSpec->append8(dotSpec, "\"]\n");\r
421 \r
422         // First produce the node defintions\r
423         //\r
424         defineDotNodes(adaptor, theTree, dotSpec);\r
425         dotSpec->append8(dotSpec, "\n");\r
426         defineDotEdges(adaptor, theTree, dotSpec);\r
427         \r
428         // Terminate the spec\r
429         //\r
430         dotSpec->append8(dotSpec, "\n}");\r
431 \r
432         // Result\r
433         //\r
434         return dotSpec;\r
435 }\r
436 \r
437 \r
438 /** Create and return a nil tree node (no token payload)\r
439  */\r
440 static  pANTLR3_BASE_TREE       \r
441 nilNode     (pANTLR3_BASE_TREE_ADAPTOR adaptor)\r
442 {\r
443         return  adaptor->create(adaptor, NULL);\r
444 }\r
445 \r
446 static  pANTLR3_BASE_TREE       \r
447 dbgNil      (pANTLR3_BASE_TREE_ADAPTOR adaptor)\r
448 {\r
449         pANTLR3_BASE_TREE t;\r
450 \r
451         t = adaptor->create                             (adaptor, NULL);\r
452         adaptor->debugger->createNode   (adaptor->debugger, t);\r
453 \r
454         return  t;\r
455 }\r
456 \r
457 /** Return a duplicate of the entire tree (implementation provided by the \r
458  *  BASE_TREE interface.)\r
459  */\r
460 static  pANTLR3_BASE_TREE       \r
461 dupTree  (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t)\r
462 {\r
463         return  adaptor->dupTreeTT(adaptor, t, NULL);\r
464 }\r
465 \r
466 pANTLR3_BASE_TREE\r
467 dupTreeTT                       (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, pANTLR3_BASE_TREE parent)\r
468 {\r
469         pANTLR3_BASE_TREE       newTree;\r
470         pANTLR3_BASE_TREE       child;\r
471         pANTLR3_BASE_TREE       newSubTree;\r
472         ANTLR3_UINT32           n;\r
473         ANTLR3_UINT32           i;\r
474 \r
475         if      (t == NULL)\r
476         {\r
477                 return NULL;\r
478         }\r
479         newTree = t->dupNode(t);\r
480 \r
481         // Ensure new subtree root has parent/child index set\r
482         //\r
483         adaptor->setChildIndex          (adaptor, newTree, t->getChildIndex(t));\r
484         adaptor->setParent                      (adaptor, newTree, parent);\r
485         n = adaptor->getChildCount      (adaptor, t);\r
486 \r
487         for     (i=0; i < n; i++)\r
488         {\r
489                 child = adaptor->getChild               (adaptor, t, i);\r
490                 newSubTree = adaptor->dupTreeTT (adaptor, child, t);\r
491                 adaptor->addChild                               (adaptor, newTree, newSubTree);\r
492         }\r
493         return  newTree;\r
494 }\r
495 \r
496 /// Sends the required debugging events for duplicating a tree\r
497 /// to the debugger.\r
498 ///\r
499 static void\r
500 simulateTreeConstruction(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE tree)\r
501 {\r
502         ANTLR3_UINT32           n;\r
503         ANTLR3_UINT32           i;\r
504         pANTLR3_BASE_TREE       child;\r
505 \r
506         // Send the create node event\r
507         //\r
508         adaptor->debugger->createNode(adaptor->debugger, tree);\r
509 \r
510         n = adaptor->getChildCount(adaptor, tree);\r
511         for     (i = 0; i < n; i++)\r
512         {\r
513                 child = adaptor->getChild(adaptor, tree, i);\r
514                 simulateTreeConstruction(adaptor, child);\r
515                 adaptor->debugger->addChild(adaptor->debugger, tree, child);\r
516         }\r
517 }\r
518 \r
519 pANTLR3_BASE_TREE\r
520 dbgDupTree              (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE tree)\r
521 {\r
522         pANTLR3_BASE_TREE t;\r
523 \r
524         // Call the normal dup tree mechanism first\r
525         //\r
526         t = adaptor->dupTreeTT(adaptor, tree, NULL);\r
527 \r
528         // In order to tell the debugger what we have just done, we now\r
529         // simulate the tree building mechanism. THis will fire\r
530         // lots of debugging events to the client and look like we\r
531         // duped the tree..\r
532         //\r
533         simulateTreeConstruction(adaptor, t);\r
534 \r
535         return t;\r
536 }\r
537 \r
538 /** Add a child to the tree t.  If child is a flat tree (a list), make all\r
539  *  in list children of t. Warning: if t has no children, but child does\r
540  *  and child isNilNode then it is ok to move children to t via\r
541  *  t.children = child.children; i.e., without copying the array.  This\r
542  *  is for construction and I'm not sure it's completely general for\r
543  *  a tree's addChild method to work this way.  Make sure you differentiate\r
544  *  between your tree's addChild and this parser tree construction addChild\r
545  *  if it's not ok to move children to t with a simple assignment.\r
546  */\r
547 static  void    \r
548 addChild (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, pANTLR3_BASE_TREE child)\r
549 {\r
550         if      (t != NULL && child != NULL)\r
551         {\r
552                 t->addChild(t, child);\r
553         }\r
554 }\r
555 static  void    \r
556 dbgAddChild (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, pANTLR3_BASE_TREE child)\r
557 {\r
558         if      (t != NULL && child != NULL)\r
559         {\r
560                 t->addChild(t, child);\r
561                 adaptor->debugger->addChild(adaptor->debugger, t, child);\r
562         }\r
563 }\r
564 /** Use the adaptor implementation to add a child node with the supplied token\r
565  */\r
566 static  void            \r
567 addChildToken           (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, pANTLR3_COMMON_TOKEN child)\r
568 {\r
569         if      (t != NULL && child != NULL)\r
570         {\r
571                 adaptor->addChild(adaptor, t, adaptor->create(adaptor, child));\r
572         }\r
573 }\r
574 static  void            \r
575 dbgAddChildToken                (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, pANTLR3_COMMON_TOKEN child)\r
576 {\r
577         pANTLR3_BASE_TREE       tc;\r
578 \r
579         if      (t != NULL && child != NULL)\r
580         {\r
581                 tc = adaptor->create(adaptor, child);\r
582                 adaptor->addChild(adaptor, t, tc);\r
583                 adaptor->debugger->addChild(adaptor->debugger, t, tc);\r
584         }\r
585 }\r
586 \r
587 /** If oldRoot is a nil root, just copy or move the children to newRoot.\r
588  *  If not a nil root, make oldRoot a child of newRoot.\r
589  *\r
590  * \code\r
591  *    old=^(nil a b c), new=r yields ^(r a b c)\r
592  *    old=^(a b c), new=r yields ^(r ^(a b c))\r
593  * \endcode\r
594  *\r
595  *  If newRoot is a nil-rooted single child tree, use the single\r
596  *  child as the new root node.\r
597  *\r
598  * \code\r
599  *    old=^(nil a b c), new=^(nil r) yields ^(r a b c)\r
600  *    old=^(a b c), new=^(nil r) yields ^(r ^(a b c))\r
601  * \endcode\r
602  *\r
603  *  If oldRoot was null, it's ok, just return newRoot (even if isNilNode).\r
604  *\r
605  * \code\r
606  *    old=null, new=r yields r\r
607  *    old=null, new=^(nil r) yields ^(nil r)\r
608  * \endcode\r
609  *\r
610  *  Return newRoot.  Throw an exception if newRoot is not a\r
611  *  simple node or nil root with a single child node--it must be a root\r
612  *  node.  If newRoot is <code>^(nil x)</endcode> return x as newRoot.\r
613  *\r
614  *  Be advised that it's ok for newRoot to point at oldRoot's\r
615  *  children; i.e., you don't have to copy the list.  We are\r
616  *  constructing these nodes so we should have this control for\r
617  *  efficiency.\r
618  */\r
619 static  pANTLR3_BASE_TREE       \r
620 becomeRoot      (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE newRootTree, pANTLR3_BASE_TREE oldRootTree)\r
621 {\r
622     pANTLR3_BASE_TREE saveRoot;\r
623 \r
624         /* Protect against tree rewrites if we are in some sort of error\r
625          * state, but have tried to recover. In C we can end up with a null pointer\r
626          * for a tree that was not produced.\r
627          */\r
628         if      (newRootTree == NULL)\r
629         {\r
630                 return  oldRootTree;\r
631         }\r
632 \r
633         /* root is just the new tree as is if there is no\r
634          * current root tree.\r
635          */\r
636         if      (oldRootTree == NULL)\r
637         {\r
638                 return  newRootTree;\r
639         }\r
640 \r
641         /* Produce ^(nil real-node)\r
642          */\r
643         if      (newRootTree->isNilNode(newRootTree))\r
644         {\r
645                 if      (newRootTree->getChildCount(newRootTree) > 1)\r
646                 {\r
647                         /* TODO: Handle tree exceptions \r
648                          */\r
649                         ANTLR3_FPRINTF(stderr, "More than one node as root! TODO: Create tree exception handling\n");\r
650                         return newRootTree;\r
651                 }\r
652 \r
653                 /* The new root is the first child, keep track of the original newRoot\r
654          * because if it was a Nil Node, then we can reuse it now.\r
655                  */\r
656         saveRoot    = newRootTree;\r
657                 newRootTree = newRootTree->getChild(newRootTree, 0);\r
658 \r
659         // Reclaim the old nilNode()\r
660         //\r
661         saveRoot->reuse(saveRoot);\r
662         }\r
663 \r
664         /* Add old root into new root. addChild takes care of the case where oldRoot\r
665          * is a flat list (nill rooted tree). All children of oldroot are added to\r
666          * new root.\r
667          */\r
668         newRootTree->addChild(newRootTree, oldRootTree);\r
669 \r
670     // If the oldroot tree was a nil node, then we know at this point\r
671     // it has become orphaned by the rewrite logic, so we tell it to do\r
672     // whatever it needs to do to be reused.\r
673     //\r
674     if  (oldRootTree->isNilNode(oldRootTree))\r
675     {\r
676         // We have taken an old Root Tree and appended all its children to the new\r
677         // root. In addition though it was a nil node, which means the generated code\r
678         // will not reuse it again, so we will reclaim it here. First we want to zero out\r
679         // any pointers it was carrying around. We are just the baseTree handler so we\r
680         // don't know necessarilly know how to do this for the real node, we just ask the tree itself\r
681         // to do it.\r
682         //\r
683         oldRootTree->reuse(oldRootTree);\r
684     }\r
685         /* Always returns new root structure\r
686          */\r
687         return  newRootTree;\r
688 \r
689 }\r
690 static  pANTLR3_BASE_TREE       \r
691 dbgBecomeRoot   (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE newRootTree, pANTLR3_BASE_TREE oldRootTree)\r
692 {\r
693         pANTLR3_BASE_TREE t;\r
694         \r
695         t = becomeRoot(adaptor, newRootTree, oldRootTree);\r
696 \r
697         adaptor->debugger->becomeRoot(adaptor->debugger, newRootTree, oldRootTree);\r
698 \r
699         return t;\r
700 }\r
701 /** Transform ^(nil x) to x \r
702  */\r
703 static  pANTLR3_BASE_TREE       \r
704    rulePostProcessing   (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE root)\r
705 {\r
706     pANTLR3_BASE_TREE saveRoot;\r
707 \r
708     // Keep track of the root we are given. If it is a nilNode, then we\r
709     // can reuse it rather than orphaning it!\r
710     //\r
711     saveRoot = root;\r
712 \r
713         if (root != NULL && root->isNilNode(root))\r
714         {\r
715                 if      (root->getChildCount(root) == 0)\r
716                 {\r
717                         root = NULL;\r
718                 }\r
719                 else if (root->getChildCount(root) == 1)\r
720                 {\r
721                         root = root->getChild(root, 0);\r
722                         root->setParent(root, NULL);\r
723                         root->setChildIndex(root, -1);\r
724 \r
725             // The root we were given was a nil node, wiht one child, which means it has\r
726             // been abandoned and would be lost in the node factory. However\r
727             // nodes can be flagged as resuable to prevent this terrible waste\r
728             //\r
729             saveRoot->reuse(saveRoot);\r
730                 }\r
731         }\r
732 \r
733         return root;\r
734 }\r
735  \r
736 /** Use the adaptor interface to set a new tree node with the supplied token\r
737  *  to the root of the tree.\r
738  */\r
739 static  pANTLR3_BASE_TREE       \r
740    becomeRootToken      (pANTLR3_BASE_TREE_ADAPTOR adaptor, void * newRoot, pANTLR3_BASE_TREE oldRoot)\r
741 {\r
742         return  adaptor->becomeRoot(adaptor, adaptor->create(adaptor, newRoot), oldRoot);\r
743 }\r
744 static  pANTLR3_BASE_TREE       \r
745 dbgBecomeRootToken      (pANTLR3_BASE_TREE_ADAPTOR adaptor, void * newRoot, pANTLR3_BASE_TREE oldRoot)\r
746 {\r
747         pANTLR3_BASE_TREE       t;\r
748 \r
749         t =     adaptor->becomeRoot(adaptor, adaptor->create(adaptor, newRoot), oldRoot);\r
750 \r
751         adaptor->debugger->becomeRoot(adaptor->debugger,t, oldRoot);\r
752 \r
753         return t;\r
754 }\r
755 \r
756 /** Use the super class supplied create() method to create a new node\r
757  *  from the supplied token.\r
758  */\r
759 static  pANTLR3_BASE_TREE       \r
760 createTypeToken (pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_COMMON_TOKEN fromToken)\r
761 {\r
762         /* Create the new token\r
763          */\r
764         fromToken = adaptor->createTokenFromToken(adaptor, fromToken);\r
765 \r
766         /* Set the type of the new token to that supplied\r
767          */\r
768         fromToken->setType(fromToken, tokenType);\r
769 \r
770         /* Return a new node based upon this token\r
771          */\r
772         return  adaptor->create(adaptor, fromToken);\r
773 }\r
774 static  pANTLR3_BASE_TREE       \r
775 dbgCreateTypeToken      (pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_COMMON_TOKEN fromToken)\r
776 {\r
777         pANTLR3_BASE_TREE t;\r
778 \r
779         t = createTypeToken(adaptor, tokenType, fromToken);\r
780 \r
781         adaptor->debugger->createNode(adaptor->debugger, t);\r
782 \r
783         return t;\r
784 }\r
785 \r
786 static  pANTLR3_BASE_TREE       \r
787 createTypeTokenText     (pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_COMMON_TOKEN fromToken, pANTLR3_UINT8 text)\r
788 {\r
789         /* Create the new token\r
790          */\r
791         fromToken = adaptor->createTokenFromToken(adaptor, fromToken);\r
792 \r
793         /* Set the type of the new token to that supplied\r
794          */\r
795         fromToken->setType(fromToken, tokenType);\r
796 \r
797         /* Set the text of the token accordingly\r
798          */\r
799         fromToken->setText8(fromToken, text);\r
800 \r
801         /* Return a new node based upon this token\r
802          */\r
803         return  adaptor->create(adaptor, fromToken);\r
804 }\r
805 static  pANTLR3_BASE_TREE       \r
806 dbgCreateTypeTokenText  (pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_COMMON_TOKEN fromToken, pANTLR3_UINT8 text)\r
807 {\r
808         pANTLR3_BASE_TREE t;\r
809 \r
810         t = createTypeTokenText(adaptor, tokenType, fromToken, text);\r
811 \r
812         adaptor->debugger->createNode(adaptor->debugger, t);\r
813 \r
814         return t;\r
815 }\r
816 \r
817 static  pANTLR3_BASE_TREE       \r
818    createTypeText       (pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_UINT8 text)\r
819 {\r
820         pANTLR3_COMMON_TOKEN    fromToken;\r
821 \r
822         /* Create the new token\r
823          */\r
824         fromToken = adaptor->createToken(adaptor, tokenType, text);\r
825 \r
826         /* Return a new node based upon this token\r
827          */\r
828         return  adaptor->create(adaptor, fromToken);\r
829 }\r
830 static  pANTLR3_BASE_TREE       \r
831    dbgCreateTypeText    (pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_UINT8 text)\r
832 {\r
833         pANTLR3_BASE_TREE t;\r
834 \r
835         t = createTypeText(adaptor, tokenType, text);\r
836 \r
837         adaptor->debugger->createNode(adaptor->debugger, t);\r
838 \r
839         return t;\r
840 \r
841 }\r
842 /** Dummy implementation - will be supplied by super class\r
843  */\r
844 static  ANTLR3_UINT32   \r
845    getType              (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t)\r
846 {\r
847         return  0;\r
848 }\r
849 \r
850 /** Dummy implementation - will be supplied by super class\r
851  */\r
852 static  void            \r
853    setType              (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, ANTLR3_UINT32 type)\r
854 {\r
855         ANTLR3_FPRINTF(stderr, "Internal error - implementor of superclass containing ANTLR3_TREE_ADAPTOR did not implement setType()\n");\r
856 }\r
857 \r
858 /** Dummy implementation - will be supplied by super class\r
859  */\r
860 static  pANTLR3_STRING  \r
861    getText              (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t)\r
862 {\r
863         ANTLR3_FPRINTF(stderr, "Internal error - implementor of superclass containing ANTLR3_TREE_ADAPTOR did not implement getText()\n");\r
864         return  NULL;\r
865 }\r
866 \r
867 /** Dummy implementation - will be supplied by super class\r
868  */\r
869 static  void            \r
870    setText              (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_STRING t)\r
871 {\r
872         ANTLR3_FPRINTF(stderr, "Internal error - implementor of superclass containing ANTLR3_TREE_ADAPTOR did not implement setText()\n");\r
873 }\r
874 /** Dummy implementation - will be supplied by super class\r
875  */\r
876 static  void            \r
877 setText8                (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_UINT8 t)\r
878 {\r
879         ANTLR3_FPRINTF(stderr, "Internal error - implementor of superclass containing ANTLR3_TREE_ADAPTOR did not implement setText()\n");\r
880 }\r
881 \r
882 static  pANTLR3_BASE_TREE       \r
883    getChild             (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE tree, ANTLR3_UINT32 i)\r
884 {\r
885         ANTLR3_FPRINTF(stderr, "Internal error - implementor of superclass containing ANTLR3_TREE_ADAPTOR did not implement getChild()\n");\r
886         return NULL;\r
887 }\r
888 \r
889 static  ANTLR3_UINT32   \r
890    getChildCount        (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE tree)\r
891 {\r
892         ANTLR3_FPRINTF(stderr, "Internal error - implementor of superclass containing ANTLR3_TREE_ADAPTOR did not implement getChildCount()\n");\r
893         return 0;\r
894 }\r
895 \r
896 /** Returns a uniqueID for the node. Because this is the C implementation\r
897  *  we can just use its address suitably converted/cast to an integer.\r
898  */\r
899 static  ANTLR3_UINT32   \r
900    getUniqueID          (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE node)\r
901 {\r
902         return  ANTLR3_UINT32_CAST(node);\r
903 }\r
904 \r
905 static  ANTLR3_BOOLEAN\r
906 isNilNode                                       (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t)\r
907 {\r
908         return t->isNilNode(t);\r
909 }\r