//------------------------------------------------------------------------- // // cloneTree Make a copy of the subtree rooted at this node. // Discard any variable references encountered along the way, // and replace with copies of the variable's definitions. // Used to replicate the expression underneath variable // references in preparation for generating the DFA tables. // //------------------------------------------------------------------------- internal virtual RBBINode CloneTree() { RBBINode n; if (fType == RBBINode.varRef) { // If the current node is a variable reference, skip over it // and clone the definition of the variable instead. n = fLeftChild.CloneTree(); } else if (fType == RBBINode.uset) { n = this; } else { n = new RBBINode(this); if (fLeftChild != null) { n.fLeftChild = fLeftChild.CloneTree(); n.fLeftChild.fParent = n; } if (fRightChild != null) { n.fRightChild = fRightChild.CloneTree(); n.fRightChild.fParent = n; } } return(n); }
//------------------------------------------------------------------------- // // flattenSets Walk the parse tree, replacing any nodes of type setRef // with a copy of the expression tree for the set. A set's // equivalent expression tree is precomputed and saved as // the left child of the uset node. // //------------------------------------------------------------------------- internal virtual void FlattenSets() { Assert.Assrt(fType != setRef); if (fLeftChild != null) { if (fLeftChild.fType == setRef) { RBBINode setRefNode = fLeftChild; RBBINode usetNode = setRefNode.fLeftChild; RBBINode replTree = usetNode.fLeftChild; fLeftChild = replTree.CloneTree(); fLeftChild.fParent = this; } else { fLeftChild.FlattenSets(); } } if (fRightChild != null) { if (fRightChild.fType == setRef) { RBBINode setRefNode = fRightChild; RBBINode usetNode = setRefNode.fLeftChild; RBBINode replTree = usetNode.fLeftChild; fRightChild = replTree.CloneTree(); fRightChild.fParent = this; // delete setRefNode; } else { fRightChild.FlattenSets(); } } }