/** Add a child to the tree t. If child is a flat tree (a list), make all * in list children of t. Warning: if t has no children, but child does * and child isNilNode then it is ok to move children to t via * t.children = child.children; i.e., without copying the array. This * is for construction and I'm not sure it's completely general for * a tree's addChild method to work this way. Make sure you differentiate * between your tree's addChild and this parser tree construction addChild * if it's not ok to move children to t with a simple assignment. */ static void addChild (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, pANTLR3_BASE_TREE child) { if (t != NULL && child != NULL) { t->addChild(t, child); } }
static void dbgAddChild (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, pANTLR3_BASE_TREE child) { if (t != NULL && child != NULL) { t->addChild(t, child); adaptor->debugger->addChild(adaptor->debugger, t, child); } }
/// Add all elements of the supplied list as children of this node /// static void addChildren (pANTLR3_BASE_TREE tree, pANTLR3_LIST kids) { ANTLR3_UINT32 i; ANTLR3_UINT32 s; s = kids->size(kids); for (i = 0; i<s; i++) { tree->addChild(tree, (pANTLR3_BASE_TREE)(kids->get(kids, i+1))); } }
/** If oldRoot is a nil root, just copy or move the children to newRoot. * If not a nil root, make oldRoot a child of newRoot. * * \code * old=^(nil a b c), new=r yields ^(r a b c) * old=^(a b c), new=r yields ^(r ^(a b c)) * \endcode * * If newRoot is a nil-rooted single child tree, use the single * child as the new root node. * * \code * old=^(nil a b c), new=^(nil r) yields ^(r a b c) * old=^(a b c), new=^(nil r) yields ^(r ^(a b c)) * \endcode * * If oldRoot was null, it's ok, just return newRoot (even if isNilNode). * * \code * old=null, new=r yields r * old=null, new=^(nil r) yields ^(nil r) * \endcode * * Return newRoot. Throw an exception if newRoot is not a * simple node or nil root with a single child node--it must be a root * node. If newRoot is <code>^(nil x)</endcode> return x as newRoot. * * Be advised that it's ok for newRoot to point at oldRoot's * children; i.e., you don't have to copy the list. We are * constructing these nodes so we should have this control for * efficiency. */ static pANTLR3_BASE_TREE becomeRoot (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE newRootTree, pANTLR3_BASE_TREE oldRootTree) { /* Protect against tree rewrites if we are in some sort of error * state, but have tried to recover. In C we can end up with a null pointer * for a tree that was not produced. */ if (newRootTree == NULL) { return oldRootTree; } /* root is just the new tree as is if there is no * current root tree. */ if (oldRootTree == NULL) { return newRootTree; } /* Produce ^(nil real-node) */ if (newRootTree->isNilNode(newRootTree)) { if (newRootTree->getChildCount(newRootTree) > 1) { /* TODO: Handle tree exceptions */ ANTLR3_FPRINTF(stderr, "More than one node as root! TODO: Create tree exception hndling\n"); return newRootTree; } /* The new root is the first child */ newRootTree = newRootTree->getChild(newRootTree, 0); } /* Add old root into new root. addChild takes care of the case where oldRoot * is a flat list (nill rooted tree). All children of oldroot are added to * new root. */ newRootTree->addChild(newRootTree, oldRootTree); /* Always returns new root structure */ return newRootTree; }
/** If oldRoot is a nil root, just copy or move the children to newRoot. * If not a nil root, make oldRoot a child of newRoot. * * \code * old=^(nil a b c), new=r yields ^(r a b c) * old=^(a b c), new=r yields ^(r ^(a b c)) * \endcode * * If newRoot is a nil-rooted single child tree, use the single * child as the new root node. * * \code * old=^(nil a b c), new=^(nil r) yields ^(r a b c) * old=^(a b c), new=^(nil r) yields ^(r ^(a b c)) * \endcode * * If oldRoot was null, it's ok, just return newRoot (even if isNilNode). * * \code * old=null, new=r yields r * old=null, new=^(nil r) yields ^(nil r) * \endcode * * Return newRoot. Throw an exception if newRoot is not a * simple node or nil root with a single child node--it must be a root * node. If newRoot is <code>^(nil x)</endcode> return x as newRoot. * * Be advised that it's ok for newRoot to point at oldRoot's * children; i.e., you don't have to copy the list. We are * constructing these nodes so we should have this control for * efficiency. */ static pANTLR3_BASE_TREE becomeRoot (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE newRootTree, pANTLR3_BASE_TREE oldRootTree) { pANTLR3_BASE_TREE saveRoot; /* Protect against tree rewrites if we are in some sort of error * state, but have tried to recover. In C we can end up with a null pointer * for a tree that was not produced. */ if (newRootTree == NULL) { return oldRootTree; } /* root is just the new tree as is if there is no * current root tree. */ if (oldRootTree == NULL) { return newRootTree; } /* Produce ^(nil real-node) */ if (newRootTree->isNilNode(newRootTree)) { if (newRootTree->getChildCount(newRootTree) > 1) { /* TODO: Handle tree exceptions */ ANTLR3_FPRINTF(stderr, "More than one node as root! TODO: Create tree exception handling\n"); return newRootTree; } /* The new root is the first child, keep track of the original newRoot * because if it was a Nil Node, then we can reuse it now. */ saveRoot = newRootTree; newRootTree = (pANTLR3_BASE_TREE)newRootTree->getChild(newRootTree, 0); // Reclaim the old nilNode() // saveRoot->reuse(saveRoot); } /* Add old root into new root. addChild takes care of the case where oldRoot * is a flat list (nill rooted tree). All children of oldroot are added to * new root. */ newRootTree->addChild(newRootTree, oldRootTree); // If the oldroot tree was a nil node, then we know at this point // it has become orphaned by the rewrite logic, so we tell it to do // whatever it needs to do to be reused. // if (oldRootTree->isNilNode(oldRootTree)) { // We have taken an old Root Tree and appended all its children to the new // root. In addition though it was a nil node, which means the generated code // will not reuse it again, so we will reclaim it here. First we want to zero out // any pointers it was carrying around. We are just the baseTree handler so we // don't know necessarilly know how to do this for the real node, we just ask the tree itself // to do it. // oldRootTree->reuse(oldRootTree); } /* Always returns new root structure */ return newRootTree; }
/** Add a child to the tree t. If child is a flat tree (a list), make all * in list children of t. Warning: if t has no children, but child does * and child isNil then it is ok to move children to t via * t.children = child.children; i.e., without copying the array. This * is for construction and I'm not sure it's completely general for * a tree's addChild method to work this way. Make sure you differentiate * between your tree's addChild and this parser tree construction addChild * if it's not ok to move children to t with a simple assignment. */ static void addChild (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, pANTLR3_BASE_TREE child) { t->addChild(t, child); }