Пример #1
0
        //******************************************************************
        #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.");
        }