/** Transform ^(nil x) to x */ static pANTLR3_BASE_TREE rulePostProcessing (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE root) { if (root != NULL && root->isNil(root) && root->getChildCount(root) == 1) { root = root->getChild(root, 0); } return root; }
/** 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. * * old=^(nil a b c), new=r yields ^(r a b c) * old=^(a b c), new=r yields ^(r ^(a b c)) * * If newRoot is a nil-rooted single child tree, use the single * child as the new root node. * * 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)) * * If oldRoot was null, it's ok, just return newRoot (even if isNil). * * old=null, new=r yields r * old=null, new=^(nil r) yields ^(nil r) * * 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 ^(nil x) 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->isNil(newRootTree)) { if (newRootTree->getChildCount(newRootTree) > 1) { /* TODO: Handle tree exceptions */ 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; }