2 * Contains the base functions that all tree adaptors start with.
\r
3 * this implementation can then be overridden by any higher implementation.
\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
12 // All rights reserved.
\r
14 // Redistribution and use in source and binary forms, with or without
\r
15 // modification, are permitted provided that the following conditions
\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
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
36 #include <antlr3basetreeadaptor.h>
\r
38 #ifdef ANTLR3_WINDOWS
\r
39 #pragma warning( disable : 4100 )
\r
42 /* Interface functions
\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
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
80 antlr3BaseTreeAdaptorInit(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_DEBUG_EVENT_LISTENER debugger)
\r
82 // Initialize the interface
\r
84 if (debugger == NULL)
\r
86 adaptor->nilNode = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR))
\r
88 adaptor->addChild = (void (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, void *))
\r
90 adaptor->becomeRoot = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, void *))
\r
92 adaptor->addChildToken = (void (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, pANTLR3_COMMON_TOKEN))
\r
94 adaptor->becomeRootToken = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, void *))
\r
96 adaptor->createTypeToken = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, ANTLR3_UINT32, pANTLR3_COMMON_TOKEN))
\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
102 adaptor->dupTree = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, void *))
\r
107 adaptor->nilNode = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR))
\r
109 adaptor->addChild = (void (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, void *))
\r
111 adaptor->becomeRoot = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, void *))
\r
113 adaptor->addChildToken = (void (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, pANTLR3_COMMON_TOKEN))
\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
123 adaptor->dupTree = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, void *))
\r
125 debugger->adaptor = adaptor;
\r
128 adaptor->dupTreeTT = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, void *))
\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
134 adaptor->setType = (void (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, ANTLR3_UINT32))
\r
136 adaptor->getText = (pANTLR3_STRING (*) (pANTLR3_BASE_TREE_ADAPTOR, void *))
\r
138 adaptor->setText8 = (void (*)(pANTLR3_BASE_TREE_ADAPTOR, pANTLR3_UINT8))
\r
140 adaptor->setText = (void (*)(pANTLR3_BASE_TREE_ADAPTOR, pANTLR3_STRING))
\r
142 adaptor->getChild = (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, ANTLR3_UINT32))
\r
144 adaptor->getChildCount = (ANTLR3_UINT32 (*)(pANTLR3_BASE_TREE_ADAPTOR, void *))
\r
146 adaptor->getUniqueID = (ANTLR3_UINT32 (*)(pANTLR3_BASE_TREE_ADAPTOR, void *))
\r
148 adaptor->isNilNode = (ANTLR3_BOOLEAN (*)(pANTLR3_BASE_TREE_ADAPTOR, void *))
\r
151 adaptor->makeDot = (pANTLR3_STRING (*)(pANTLR3_BASE_TREE_ADAPTOR, void *))
\r
154 /* Remaining functions filled in by the caller.
\r
160 defineDotNodes(pANTLR3_BASE_TREE_ADAPTOR adaptor, void * t, pANTLR3_STRING dotSpec )
\r
162 // How many nodes are we talking about?
\r
166 pANTLR3_BASE_TREE child;
\r
168 pANTLR3_STRING text;
\r
177 nCount = adaptor->getChildCount(adaptor, t);
\r
181 // This will already have been included as a child of another node
\r
182 // so there is nothing to add.
\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
190 for (i = 0; i<nCount; i++)
\r
193 // Pick up a pointer for the child
\r
195 child = adaptor->getChild(adaptor, t, i);
\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
204 switch(text->charAt(text, j))
\r
208 dotSpec->append8(dotSpec, "\\\"");
\r
213 dotSpec->append8(dotSpec, "\\n");
\r
218 dotSpec->append8(dotSpec, "\\r");
\r
223 dotSpec->addc(dotSpec, text->charAt(text, j));
\r
227 dotSpec->append8(dotSpec, "\"]\n");
\r
229 // And now define the children of this child (if any)
\r
231 defineDotNodes(adaptor, child, dotSpec);
\r
240 defineDotEdges(pANTLR3_BASE_TREE_ADAPTOR adaptor, void * t, pANTLR3_STRING dotSpec)
\r
242 // How many nodes are we talking about?
\r
249 // No tree, so do nothing
\r
256 nCount = adaptor->getChildCount(adaptor, t);
\r
260 // This will already have been included as a child of another node
\r
261 // so there is nothing to add.
\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
269 for (i=0; i<nCount; i++)
\r
271 pANTLR3_BASE_TREE child;
\r
273 pANTLR3_STRING text;
\r
278 child = adaptor->getChild(adaptor, t, i);
\r
280 // Create the edge relation
\r
282 sprintf(buff, "\t\tn%p -> n%p\t\t// ", t, child);
\r
284 dotSpec->append8(dotSpec, buff);
\r
286 // Document the relationship
\r
288 text = adaptor->getText(adaptor, t);
\r
289 for (j = 0; j < (ANTLR3_INT32)(text->len); j++)
\r
291 switch(text->charAt(text, j))
\r
295 dotSpec->append8(dotSpec, "\\\"");
\r
300 dotSpec->append8(dotSpec, "\\n");
\r
305 dotSpec->append8(dotSpec, "\\r");
\r
310 dotSpec->addc(dotSpec, text->charAt(text, j));
\r
315 dotSpec->append8(dotSpec, " -> ");
\r
317 text = adaptor->getText(adaptor, child);
\r
318 for (j = 0; j < (ANTLR3_INT32)(text->len); j++)
\r
320 switch(text->charAt(text, j))
\r
324 dotSpec->append8(dotSpec, "\\\"");
\r
329 dotSpec->append8(dotSpec, "\\n");
\r
334 dotSpec->append8(dotSpec, "\\r");
\r
339 dotSpec->addc(dotSpec, text->charAt(text, j));
\r
343 dotSpec->append8(dotSpec, "\n");
\r
346 // Define edges for this child
\r
348 defineDotEdges(adaptor, child, dotSpec);
\r
356 /// Produce a DOT specification for graphviz
\r
358 static pANTLR3_STRING
\r
359 makeDot (pANTLR3_BASE_TREE_ADAPTOR adaptor, void * theTree)
\r
361 // The string we are building up
\r
363 pANTLR3_STRING dotSpec;
\r
365 pANTLR3_STRING text;
\r
368 dotSpec = adaptor->strFactory->newStr8
\r
371 adaptor->strFactory,
\r
373 // Default look and feel
\r
377 "\tordering=out;\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
384 if (theTree == NULL)
\r
386 // No tree, so create a blank spec
\r
388 dotSpec->append8(dotSpec, "n0[label=\"EMPTY TREE\"]\n");
\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
397 switch(text->charAt(text, j))
\r
401 dotSpec->append8(dotSpec, "\\\"");
\r
406 dotSpec->append8(dotSpec, "\\n");
\r
411 dotSpec->append8(dotSpec, "\\r");
\r
416 dotSpec->addc(dotSpec, text->charAt(text, j));
\r
420 dotSpec->append8(dotSpec, "\"]\n");
\r
422 // First produce the node defintions
\r
424 defineDotNodes(adaptor, theTree, dotSpec);
\r
425 dotSpec->append8(dotSpec, "\n");
\r
426 defineDotEdges(adaptor, theTree, dotSpec);
\r
428 // Terminate the spec
\r
430 dotSpec->append8(dotSpec, "\n}");
\r
438 /** Create and return a nil tree node (no token payload)
\r
440 static pANTLR3_BASE_TREE
\r
441 nilNode (pANTLR3_BASE_TREE_ADAPTOR adaptor)
\r
443 return adaptor->create(adaptor, NULL);
\r
446 static pANTLR3_BASE_TREE
\r
447 dbgNil (pANTLR3_BASE_TREE_ADAPTOR adaptor)
\r
449 pANTLR3_BASE_TREE t;
\r
451 t = adaptor->create (adaptor, NULL);
\r
452 adaptor->debugger->createNode (adaptor->debugger, t);
\r
457 /** Return a duplicate of the entire tree (implementation provided by the
\r
458 * BASE_TREE interface.)
\r
460 static pANTLR3_BASE_TREE
\r
461 dupTree (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t)
\r
463 return adaptor->dupTreeTT(adaptor, t, NULL);
\r
467 dupTreeTT (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, pANTLR3_BASE_TREE parent)
\r
469 pANTLR3_BASE_TREE newTree;
\r
470 pANTLR3_BASE_TREE child;
\r
471 pANTLR3_BASE_TREE newSubTree;
\r
479 newTree = t->dupNode(t);
\r
481 // Ensure new subtree root has parent/child index set
\r
483 adaptor->setChildIndex (adaptor, newTree, t->getChildIndex(t));
\r
484 adaptor->setParent (adaptor, newTree, parent);
\r
485 n = adaptor->getChildCount (adaptor, t);
\r
487 for (i=0; i < n; i++)
\r
489 child = adaptor->getChild (adaptor, t, i);
\r
490 newSubTree = adaptor->dupTreeTT (adaptor, child, t);
\r
491 adaptor->addChild (adaptor, newTree, newSubTree);
\r
496 /// Sends the required debugging events for duplicating a tree
\r
497 /// to the debugger.
\r
500 simulateTreeConstruction(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE tree)
\r
504 pANTLR3_BASE_TREE child;
\r
506 // Send the create node event
\r
508 adaptor->debugger->createNode(adaptor->debugger, tree);
\r
510 n = adaptor->getChildCount(adaptor, tree);
\r
511 for (i = 0; i < n; i++)
\r
513 child = adaptor->getChild(adaptor, tree, i);
\r
514 simulateTreeConstruction(adaptor, child);
\r
515 adaptor->debugger->addChild(adaptor->debugger, tree, child);
\r
520 dbgDupTree (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE tree)
\r
522 pANTLR3_BASE_TREE t;
\r
524 // Call the normal dup tree mechanism first
\r
526 t = adaptor->dupTreeTT(adaptor, tree, NULL);
\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
533 simulateTreeConstruction(adaptor, t);
\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
548 addChild (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, pANTLR3_BASE_TREE child)
\r
550 if (t != NULL && child != NULL)
\r
552 t->addChild(t, child);
\r
556 dbgAddChild (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, pANTLR3_BASE_TREE child)
\r
558 if (t != NULL && child != NULL)
\r
560 t->addChild(t, child);
\r
561 adaptor->debugger->addChild(adaptor->debugger, t, child);
\r
564 /** Use the adaptor implementation to add a child node with the supplied token
\r
567 addChildToken (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, pANTLR3_COMMON_TOKEN child)
\r
569 if (t != NULL && child != NULL)
\r
571 adaptor->addChild(adaptor, t, adaptor->create(adaptor, child));
\r
575 dbgAddChildToken (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, pANTLR3_COMMON_TOKEN child)
\r
577 pANTLR3_BASE_TREE tc;
\r
579 if (t != NULL && child != NULL)
\r
581 tc = adaptor->create(adaptor, child);
\r
582 adaptor->addChild(adaptor, t, tc);
\r
583 adaptor->debugger->addChild(adaptor->debugger, t, tc);
\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
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
595 * If newRoot is a nil-rooted single child tree, use the single
\r
596 * child as the new root node.
\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
603 * If oldRoot was null, it's ok, just return newRoot (even if isNilNode).
\r
606 * old=null, new=r yields r
\r
607 * old=null, new=^(nil r) yields ^(nil r)
\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
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
619 static pANTLR3_BASE_TREE
\r
620 becomeRoot (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE newRootTree, pANTLR3_BASE_TREE oldRootTree)
\r
622 pANTLR3_BASE_TREE saveRoot;
\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
628 if (newRootTree == NULL)
\r
630 return oldRootTree;
\r
633 /* root is just the new tree as is if there is no
\r
634 * current root tree.
\r
636 if (oldRootTree == NULL)
\r
638 return newRootTree;
\r
641 /* Produce ^(nil real-node)
\r
643 if (newRootTree->isNilNode(newRootTree))
\r
645 if (newRootTree->getChildCount(newRootTree) > 1)
\r
647 /* TODO: Handle tree exceptions
\r
649 ANTLR3_FPRINTF(stderr, "More than one node as root! TODO: Create tree exception handling\n");
\r
650 return newRootTree;
\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
656 saveRoot = newRootTree;
\r
657 newRootTree = newRootTree->getChild(newRootTree, 0);
\r
659 // Reclaim the old nilNode()
\r
661 saveRoot->reuse(saveRoot);
\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
668 newRootTree->addChild(newRootTree, oldRootTree);
\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
674 if (oldRootTree->isNilNode(oldRootTree))
\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
683 oldRootTree->reuse(oldRootTree);
\r
685 /* Always returns new root structure
\r
687 return newRootTree;
\r
690 static pANTLR3_BASE_TREE
\r
691 dbgBecomeRoot (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE newRootTree, pANTLR3_BASE_TREE oldRootTree)
\r
693 pANTLR3_BASE_TREE t;
\r
695 t = becomeRoot(adaptor, newRootTree, oldRootTree);
\r
697 adaptor->debugger->becomeRoot(adaptor->debugger, newRootTree, oldRootTree);
\r
701 /** Transform ^(nil x) to x
\r
703 static pANTLR3_BASE_TREE
\r
704 rulePostProcessing (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE root)
\r
706 pANTLR3_BASE_TREE saveRoot;
\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
713 if (root != NULL && root->isNilNode(root))
\r
715 if (root->getChildCount(root) == 0)
\r
719 else if (root->getChildCount(root) == 1)
\r
721 root = root->getChild(root, 0);
\r
722 root->setParent(root, NULL);
\r
723 root->setChildIndex(root, -1);
\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
729 saveRoot->reuse(saveRoot);
\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
739 static pANTLR3_BASE_TREE
\r
740 becomeRootToken (pANTLR3_BASE_TREE_ADAPTOR adaptor, void * newRoot, pANTLR3_BASE_TREE oldRoot)
\r
742 return adaptor->becomeRoot(adaptor, adaptor->create(adaptor, newRoot), oldRoot);
\r
744 static pANTLR3_BASE_TREE
\r
745 dbgBecomeRootToken (pANTLR3_BASE_TREE_ADAPTOR adaptor, void * newRoot, pANTLR3_BASE_TREE oldRoot)
\r
747 pANTLR3_BASE_TREE t;
\r
749 t = adaptor->becomeRoot(adaptor, adaptor->create(adaptor, newRoot), oldRoot);
\r
751 adaptor->debugger->becomeRoot(adaptor->debugger,t, oldRoot);
\r
756 /** Use the super class supplied create() method to create a new node
\r
757 * from the supplied token.
\r
759 static pANTLR3_BASE_TREE
\r
760 createTypeToken (pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_COMMON_TOKEN fromToken)
\r
762 /* Create the new token
\r
764 fromToken = adaptor->createTokenFromToken(adaptor, fromToken);
\r
766 /* Set the type of the new token to that supplied
\r
768 fromToken->setType(fromToken, tokenType);
\r
770 /* Return a new node based upon this token
\r
772 return adaptor->create(adaptor, fromToken);
\r
774 static pANTLR3_BASE_TREE
\r
775 dbgCreateTypeToken (pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_COMMON_TOKEN fromToken)
\r
777 pANTLR3_BASE_TREE t;
\r
779 t = createTypeToken(adaptor, tokenType, fromToken);
\r
781 adaptor->debugger->createNode(adaptor->debugger, t);
\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
789 /* Create the new token
\r
791 fromToken = adaptor->createTokenFromToken(adaptor, fromToken);
\r
793 /* Set the type of the new token to that supplied
\r
795 fromToken->setType(fromToken, tokenType);
\r
797 /* Set the text of the token accordingly
\r
799 fromToken->setText8(fromToken, text);
\r
801 /* Return a new node based upon this token
\r
803 return adaptor->create(adaptor, fromToken);
\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
808 pANTLR3_BASE_TREE t;
\r
810 t = createTypeTokenText(adaptor, tokenType, fromToken, text);
\r
812 adaptor->debugger->createNode(adaptor->debugger, t);
\r
817 static pANTLR3_BASE_TREE
\r
818 createTypeText (pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_UINT8 text)
\r
820 pANTLR3_COMMON_TOKEN fromToken;
\r
822 /* Create the new token
\r
824 fromToken = adaptor->createToken(adaptor, tokenType, text);
\r
826 /* Return a new node based upon this token
\r
828 return adaptor->create(adaptor, fromToken);
\r
830 static pANTLR3_BASE_TREE
\r
831 dbgCreateTypeText (pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_UINT8 text)
\r
833 pANTLR3_BASE_TREE t;
\r
835 t = createTypeText(adaptor, tokenType, text);
\r
837 adaptor->debugger->createNode(adaptor->debugger, t);
\r
842 /** Dummy implementation - will be supplied by super class
\r
844 static ANTLR3_UINT32
\r
845 getType (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t)
\r
850 /** Dummy implementation - will be supplied by super class
\r
853 setType (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, ANTLR3_UINT32 type)
\r
855 ANTLR3_FPRINTF(stderr, "Internal error - implementor of superclass containing ANTLR3_TREE_ADAPTOR did not implement setType()\n");
\r
858 /** Dummy implementation - will be supplied by super class
\r
860 static pANTLR3_STRING
\r
861 getText (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t)
\r
863 ANTLR3_FPRINTF(stderr, "Internal error - implementor of superclass containing ANTLR3_TREE_ADAPTOR did not implement getText()\n");
\r
867 /** Dummy implementation - will be supplied by super class
\r
870 setText (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_STRING t)
\r
872 ANTLR3_FPRINTF(stderr, "Internal error - implementor of superclass containing ANTLR3_TREE_ADAPTOR did not implement setText()\n");
\r
874 /** Dummy implementation - will be supplied by super class
\r
877 setText8 (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_UINT8 t)
\r
879 ANTLR3_FPRINTF(stderr, "Internal error - implementor of superclass containing ANTLR3_TREE_ADAPTOR did not implement setText()\n");
\r
882 static pANTLR3_BASE_TREE
\r
883 getChild (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE tree, ANTLR3_UINT32 i)
\r
885 ANTLR3_FPRINTF(stderr, "Internal error - implementor of superclass containing ANTLR3_TREE_ADAPTOR did not implement getChild()\n");
\r
889 static ANTLR3_UINT32
\r
890 getChildCount (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE tree)
\r
892 ANTLR3_FPRINTF(stderr, "Internal error - implementor of superclass containing ANTLR3_TREE_ADAPTOR did not implement getChildCount()\n");
\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
899 static ANTLR3_UINT32
\r
900 getUniqueID (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE node)
\r
902 return ANTLR3_UINT32_CAST(node);
\r
905 static ANTLR3_BOOLEAN
\r
906 isNilNode (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t)
\r
908 return t->isNilNode(t);
\r