//****************************************************************** #region [ReplaceCurrentMatchingBranch() Method] //****************************************************************** /// <summary> /// Replaces the sub-tree dominated by the CurrentParseTreeNode, /// using the tree dominated by the ReplacePatternRoot as a pattern. /// Corresponding nodes (matched by a find-pattern node with the /// same label as the replace-pattern node) are copied from the /// MatchingNodes stack and their features are merged with features /// from the replace pattern. The replaced nodes in the new sub-tree /// are also stored in the ReplacedNodes stack. /// </summary> public void ReplaceCurrentMatchingBranch() { Debug.WriteLineIf(VerboseDebugging, "ReplaceAlgorithm.ReplaceCurrentMatchingBranch() called."); //************************************************************** // Validate the current state. if (ParseTreeRoot == null) { string sMessage = "ReplaceCurrentMatchingBranch() " + "called with an invalid state: " + "ParseTreeRoot is null."; throw new Exception(sMessage); } if (MatchingNodes.Count < 1) { string sMessage = "ReplaceCurrentMatchingBranch() " + "called with an invalid state: " + "MatchingNodes is empty."; throw new Exception(sMessage); } foreach (SyntaxNodePair oNodePair in MatchingNodes) { if (oNodePair.ParseTreeNode == null) { string sMessage = "ReplaceCurrentMatchingBranch() " + "called with an invalid state: " + "MatchingNodes contains an item where " + ".ParseTreeNode is null."; throw new Exception(sMessage); } if (oNodePair.FindPatternNode == null) { string sMessage = "ReplaceCurrentMatchingBranch() " + "called with an invalid state: " + "MatchingNodes contains an item where " + ".FindPatternNode is null."; throw new Exception(sMessage); } } if (ReplacedNodes.Count > 0) { string sMessage = "ReplaceCurrentMatchingBranch() " + "called with an invalid state: " + "ReplacedNodes is not empty."; throw new Exception(sMessage); } if (CurrentParseTreeNode == null) { string sMessage = "ReplaceCurrentMatchingBranch() " + "called with an invalid state: " + "CurrentParseTreeNode is null."; throw new Exception(sMessage); } //************************************************************** // Clear the ReplacedNodes list. ReplacedNodes.Clear(); //************************************************************** // If ReplacePatternRoot is null, use an empty SyntaxNode (one // with no features and no children) instead. SyntaxNode oReplacePatternRoot = ReplacePatternRoot; if (oReplacePatternRoot == null) { oReplacePatternRoot = new SyntaxNode(); } //************************************************************** // Use the oReplacePatternRoot and the MatchingNodes list to // create a new branch to replace the CurrentParseTreeNode. SyntaxNode oNewBranch = CopyNodeAndChildren(oReplacePatternRoot); //************************************************************** // BUGBUG: We may need to make another pass through the new // branch to: // // (1) copy features (or substrings) from another node using a // path <../DP/NP/featurename>. // // (2) recompute any feature values after other features have // changed (like changes to the word string because // morphology strings have changed). //************************************************************** // If the new branch is null, use an empty SyntaxNode (one with // no features and no children) instead, and add this to the // ReplacedNodes list. if (oNewBranch == null) { oNewBranch = new SyntaxNode(); SyntaxNodeTriple oNodeTriple = new SyntaxNodeTriple(); oNodeTriple.ParseTreeNode = oNewBranch; oNodeTriple.FindPatternNode = null; oNodeTriple.ReplacePatternNode = new SyntaxNode(); ReplacedNodes.Push(oNodeTriple); } Debug.Assert(ReplacedNodes.Count > 0); //************************************************************** // If the CurrentParseTreeNode has a parent node, find its // index in the parent's ChildNodes collection, and replace the // child at that index with the new branch. SyntaxNode oParent = CurrentParseTreeNode.ParentNode; if (oParent != null) { int iIndex = oParent.ChildNodes.IndexOf(CurrentParseTreeNode); oParent.ChildNodes.Insert(iIndex, oNewBranch); oParent.ChildNodes.Remove(CurrentParseTreeNode); } //************************************************************** // If the CurrentParseTreeNode is the same as the ParseTreeRoot, // replace the ParseTreeRoot with the new branch. if (CurrentParseTreeNode == ParseTreeRoot) { ParseTreeRoot = oNewBranch; } //************************************************************** // Set CurrentParseTreeNode to the new branch. CurrentParseTreeNode = oNewBranch; //************************************************************** // Dump the ReplacedNodes list for verbose debugging. if (VerboseDebugging) { foreach (SyntaxNodeTriple oNodeTriple in ReplacedNodes) { Debug.Assert(oNodeTriple.ParseTreeNode != null); Debug.Assert(oNodeTriple.ReplacePatternNode != null); } Debug.WriteLine("ReplacedNodes: " + ReplacedNodes.ToString() + "."); } Debug.WriteLineIf(VerboseDebugging, "ReplaceAlgorithm.ReplaceCurrentMatchingBranch() returns."); }