コード例 #1
0
        //******************************************************************
        #region [Pop() Method]
        //******************************************************************
        /// <summary>
        /// Removes and returns the item at the top of the stack.
        /// </summary>
        public SyntaxNodeTriple Pop()
        {
            Debug.Assert(InnerList.Count > 0);

            SyntaxNodeTriple oNodeTriple
                = (SyntaxNodeTriple)InnerList[InnerList.Count - 1];

            InnerList.RemoveAt(InnerList.Count - 1);
            return(oNodeTriple);
        }
コード例 #2
0
        //******************************************************************
        #region [Push() Method]
        //******************************************************************
        /// <summary>
        /// Inserts an item at the top of the stack.
        /// </summary>
        public void Push(SyntaxNodeTriple oNodeTriple)
        {
            Debug.Assert(oNodeTriple != null);

            if (oNodeTriple == null)
            {
                string sMessage = "Invalid argument: "
                                  + "SyntaxNodeTripleStack cannot push a null item.";
                throw new Exception(sMessage);
            }

            InnerList.Add(oNodeTriple);
        }
コード例 #3
0
        //******************************************************************
        /// <summary>
        /// For the given oReplacePatternNode, this method finds the
        /// corresponding find-pattern node and the parse-tree node it
        /// matched. (The parse-tree node must be in the branch indicated by
        /// oMorphologyParseRoot if this optional argument is not null.) A
        /// new node is created by copying features from the parse-tree node
        /// and merging features from the oReplacePatternNode. Then children
        /// are copied recursively either from the parse-tree node or from
        /// the oReplacePatternNode. Returns null if the oReplacePatternNode
        /// was optional and the parse-tree node was not found. Otherwise,
        /// returns the new node after adding it to the ReplacedNodes list.
        /// (Note that this method calls the CopyLeafAndChildren() method if
        /// it determines that the node is a leaf node.)
        /// </summary>
        SyntaxNode CopyNodeAndChildren(SyntaxNode oReplacePatternNode,
			SyntaxNode oMorphologyParseRoot)
        {
            Debug.Assert(oReplacePatternNode != null);

            //**************************************************************
            // For the given oReplacePatternNode, find the corresponding
            // find-pattern node and the parse-tree node it matched:
            //
            // Search the MatchingNodes list for a node pair where the
            // .FindPatternNode has the same label as the given
            // oReplacePatternNode.
            //
            // If oMorphologyParseRoot is not null, restrict this search to
            // node pairs where the .ParseTreeNode is contained in the
            // branch dominated by this oMorphologyParseRoot.
            //
            // If a matching node pair is found, set oParseTreeNode and
            // oFindPatternNode to the node-pair values. Otherwise, set
            // oParseTreeNode and oFindPatternNode both to null.

            SyntaxNode oParseTreeNode = null;
            SyntaxNode oFindPatternNode = null;
            SyntaxNodePair oNodePair = FindMatchingPairFromLabel(
                oReplacePatternNode.Label,oMorphologyParseRoot);
            if (oNodePair != null)
            {
                oParseTreeNode = oNodePair.ParseTreeNode;
                oFindPatternNode = oNodePair.FindPatternNode;
            }

            //**************************************************************
            // If a matching node pair was not found and oReplacePatternNode
            // is optional, nothing will be copied, so return null.

            if ((oNodePair == null) && (oReplacePatternNode.IsOptionalNode))
            {
                return null;
            }

            //**************************************************************
            // If this is a leaf node, call CopyLeafAndChildren() instead.
            //
            // Each child of a syntax leaf is the root of a morphology
            // parse. (A syntax leaf may have one or more alternative
            // morphology parses.) CopyLeafAndChildren() is called because
            // a different algorithm is needed to copy these children.

            bool bIsSyntaxLeaf = false;
            if (oParseTreeNode != null)
            {
                if (oParseTreeNode.IsSyntaxLeaf)
                {
                    bIsSyntaxLeaf = true;
                }
            }
            if (oReplacePatternNode.IsSyntaxLeaf)
            {
                bIsSyntaxLeaf = true;
            }
            if (bIsSyntaxLeaf)
            {
                return CopyLeafAndChildren(oReplacePatternNode);
            }

            //**************************************************************
            // Create a new parse-tree node by copying the features from the
            // matching oParseTreeNode (if found) and then merging the
            // features from oReplacePatternNode.

            if (VerboseDebugging)
            {
                string sParseString = "null";
                if (oParseTreeNode != null)
                {
                    sParseString = oParseTreeNode.ToString();
                }
                string sReplaceString = "null";
                if (oReplacePatternNode != null)
                {
                    sReplaceString = oReplacePatternNode.ToString();
                }
                Debug.WriteLine("Copying node: CopyFeatures("
                    + sParseString + "," + sReplaceString + ").");
            }

            SyntaxNode oNewNode
                = CopyFeatures(oParseTreeNode,oReplacePatternNode);

            //**************************************************************
            // Check if any children are specified by oFindPatternNode or
            // oReplacePatternNode.

            bool bFindPatternHasChildren = false;
            if (oFindPatternNode != null)
            {
                if (oFindPatternNode.ChildNodes.Count > 0)
                {
                    bFindPatternHasChildren = true;
                }
            }
            bool bReplacePatternHasChildren = false;
            if (oReplacePatternNode.ChildNodes.Count > 0)
            {
                bReplacePatternHasChildren = true;
            }

            //**************************************************************
            // Copy children either from the matching oParseTreeNode or from
            // the oReplacePatternNode:
            //
            // If oParseTreeNode is not null and no children are specified
            // by oFindPatternNode or oReplacePatternNode, copy the
            // oParseTreeNode children.
            //
            // Otherwise, copy the oReplacePatternNode children.

            if ((oParseTreeNode != null) && (! bFindPatternHasChildren)
                && (! bReplacePatternHasChildren))
            {
                //**********************************************************
                // Copy the oParseTreeNode children.

                foreach (SyntaxNode oParseChild in
                    oParseTreeNode.ChildNodes)
                {
                    SyntaxNode oNewChild = oParseChild.CloneBranch();
                    oNewNode.ChildNodes.Add(oNewChild);
                }
            }
            else
            {
                //**********************************************************
                // Copy the oReplacePatternNode children.

                foreach (SyntaxNode oReplaceChild in
                    oReplacePatternNode.ChildNodes)
                {
                    SyntaxNode oNewChild = CopyNodeAndChildren(
                        oReplaceChild,oMorphologyParseRoot);
                    if (oNewChild != null)
                    {
                        oNewNode.ChildNodes.Add(oNewChild);
                    }
                }
            }

            //**************************************************************
            // Return the new parse-tree node after adding it to the
            // ReplacedNodes list.

            SyntaxNodeTriple oNodeTriple = new SyntaxNodeTriple();
            oNodeTriple.ParseTreeNode = oNewNode;
            oNodeTriple.FindPatternNode = oFindPatternNode;
            oNodeTriple.ReplacePatternNode = oReplacePatternNode;
            ReplacedNodes.Push(oNodeTriple);
            return oNewNode;
        }
コード例 #4
0
        //******************************************************************
        /// <summary>
        /// For the given oReplacePatternNode, this method finds the
        /// corresponding find-pattern node and the parse-tree node it
        /// matched. A new node is created by copying features from the
        /// parse-tree node and merging features from the
        /// oReplacePatternNode. Then children are copied recursively from
        /// the parse-tree node. Children are also copied recursively from
        /// the oReplacePatternNode if they do not correspond to children of
        /// the parse-tree node. Returns null if the oReplacePatternNode was
        /// optional and the parse-tree node was not found. Otherwise,
        /// returns the new node after adding it to the ReplacedNodes list.
        /// (Note that this method is only for copying leaf nodes.)
        /// </summary>
        SyntaxNode CopyLeafAndChildren(SyntaxNode oReplacePatternNode)
        {
            Debug.Assert(oReplacePatternNode != null);

            //**************************************************************
            // For the given oReplacePatternNode, find the corresponding
            // find-pattern node and the parse-tree node it matched:
            //
            // Search the MatchingNodes list for a node pair where the
            // .FindPatternNode has the same label as the given
            // oReplacePatternNode.
            //
            // If a matching node pair is found, set oParseTreeNode and
            // oFindPatternNode to the node-pair values. Otherwise, set
            // oParseTreeNode and oFindPatternNode both to null.

            SyntaxNode oParseTreeNode = null;
            SyntaxNode oFindPatternNode = null;
            SyntaxNodePair oNodePair =
                FindMatchingPairFromLabel(oReplacePatternNode.Label);
            if (oNodePair != null)
            {
                oParseTreeNode = oNodePair.ParseTreeNode;
                oFindPatternNode = oNodePair.FindPatternNode;
            }

            //**************************************************************
            // If a matching node pair was not found and oReplacePatternNode
            // is optional, nothing will be copied, so return null.

            if ((oNodePair == null) && (oReplacePatternNode.IsOptionalNode))
            {
                return null;
            }

            //**************************************************************
            // This method should only be called for leaf nodes.

            if (oParseTreeNode != null)
            {
                Debug.Assert(oParseTreeNode.IsSyntaxLeaf
                    || oReplacePatternNode.IsSyntaxLeaf);
            }
            else
            {
                Debug.Assert(oReplacePatternNode.IsSyntaxLeaf);
            }

            //**************************************************************
            // Create a new parse-tree node by copying the features from the
            // matching oParseTreeNode (if found) and then merging the
            // features from oReplacePatternNode.

            if (VerboseDebugging)
            {
                string sParseString = "null";
                if (oParseTreeNode != null)
                {
                    sParseString = oParseTreeNode.ToString();
                }
                string sReplaceString = "null";
                if (oReplacePatternNode != null)
                {
                    sReplaceString = oReplacePatternNode.ToString();
                }
                Debug.WriteLine("Copying leaf: CopyFeatures("
                    + sParseString + "," + sReplaceString + ").");
            }

            SyntaxNode oNewNode
                = CopyFeatures(oParseTreeNode,oReplacePatternNode);

            //**************************************************************
            // Each child of a syntax leaf is the root of a morphology
            // parse. (A syntax leaf may have one or more alternative
            // morphology parses.)
            //
            // Each child will be copied recursively from oParseTreeNode.
            // Additional children will also be copied recursively from
            // oReplacePatternNode if they do not correspond to children of
            // oParseTreeNode.
            //
            // Create a list to keep track of the oReplacePatternNode
            // children as they are used. (A replace-pattern child is marked
            // as used if it has the same label as a find-pattern child
            // matching one of the oParseTreeNode children.)

            ArrayList oUsedReplaceChildren = new ArrayList();

            //**************************************************************
            // Copy the oParseTreeNode children.

            if (oParseTreeNode != null)
            {
                foreach (SyntaxNode oParseChild in
                    oParseTreeNode.ChildNodes)
                {
                    //******************************************************
                    // Look for the find-pattern node that matched this
                    // parse-tree child:
                    //
                    // Search the MatchingNodes list for a node pair where
                    // the .ParseTreeNode is the same as oParseChild.
                    //
                    // If found, set oFindChild to the .FindPatternNode
                    // value from the node pair. Otherwise, set oFindChild
                    // to null.

                    SyntaxNodePair oChildNodePair
                        = FindMatchingPairFromNode(oParseChild);
                    SyntaxNode oFindChild = null;
                    if (oChildNodePair != null)
                    {
                        oFindChild = oChildNodePair.FindPatternNode;
                    }

                    //******************************************************
                    // If oFindChild is null (no find-pattern matched
                    // this parse-tree child), copy oParseChild.
                    //
                    // Otherwise, copy each oReplacePatternNode child that
                    // has the same label as oFindChild.

                    if (oFindChild == null)
                    {
                        //**************************************************
                        // Copy oParseChild.

                        SyntaxNode oNewChild = oParseChild.CloneBranch();
                        oNewNode.ChildNodes.Add(oNewChild);
                    }
                    else
                    {
                        //**************************************************
                        // Copy each oReplacePatternNode child that has the
                        // same label as oFindChild.

                        foreach (SyntaxNode oReplaceChild in
                            oReplacePatternNode.ChildNodes)
                        {
                            if (oReplaceChild.Label == oFindChild.Label)
                            {
                                //******************************************
                                // Copy the oReplacePatternNode child.
                                //
                                // Since oParseTreeNode is a syntax leaf,
                                // each of its children is the root of a
                                // morphology parse. So oParseChild is used
                                // as the oMorphologyParseRoot argument to
                                // the CopyNodeAndChildren() method.

                                SyntaxNode oNewChild = CopyNodeAndChildren(
                                    oReplaceChild,oParseChild);
                                if (oNewChild != null)
                                {
                                    oNewNode.ChildNodes.Add(oNewChild);
                                }

                                //******************************************
                                // Add this oReplaceChild to the list of
                                // oUsedReplaceChildren (if not already
                                // there).

                                if (! oUsedReplaceChildren
                                    .Contains(oReplaceChild))
                                {
                                    oUsedReplaceChildren.Add(oReplaceChild);
                                }
                            }
                        }
                    }
                }
            }

            //**************************************************************
            // Copy any oReplacePatternNode children that have not yet been
            // used.

            foreach (SyntaxNode oReplaceChild in
                oReplacePatternNode.ChildNodes)
            {
                if (! oUsedReplaceChildren.Contains(oReplaceChild))
                {
                    SyntaxNode oNewChild =
                        CopyNodeAndChildren(oReplaceChild);
                    if (oNewChild != null)
                    {
                        oNewNode.ChildNodes.Add(oNewChild);
                    }
                }
            }

            //**************************************************************
            // Return the new parse-tree node after adding it to the
            // ReplacedNodes list.

            SyntaxNodeTriple oNodeTriple = new SyntaxNodeTriple();
            oNodeTriple.ParseTreeNode = oNewNode;
            oNodeTriple.FindPatternNode = oFindPatternNode;
            oNodeTriple.ReplacePatternNode = oReplacePatternNode;
            ReplacedNodes.Push(oNodeTriple);
            return oNewNode;
        }
コード例 #5
0
        //******************************************************************
        /// <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.");
        }
コード例 #6
0
        //******************************************************************
        #region [CopyLeafAndChildren() Method]
        //******************************************************************
        /// <summary>
        /// For the given oReplacePatternNode, this method finds the
        /// corresponding find-pattern node and the parse-tree node it
        /// matched. A new node is created by copying features from the
        /// parse-tree node and merging features from the
        /// oReplacePatternNode. Then children are copied recursively from
        /// the parse-tree node. Children are also copied recursively from
        /// the oReplacePatternNode if they do not correspond to children of
        /// the parse-tree node. Returns null if the oReplacePatternNode was
        /// optional and the parse-tree node was not found. Otherwise,
        /// returns the new node after adding it to the ReplacedNodes list.
        /// (Note that this method is only for copying leaf nodes.)
        /// </summary>
        SyntaxNode CopyLeafAndChildren(SyntaxNode oReplacePatternNode)
        {
            Debug.Assert(oReplacePatternNode != null);

            //**************************************************************
            // For the given oReplacePatternNode, find the corresponding
            // find-pattern node and the parse-tree node it matched:
            //
            // Search the MatchingNodes list for a node pair where the
            // .FindPatternNode has the same label as the given
            // oReplacePatternNode.
            //
            // If a matching node pair is found, set oParseTreeNode and
            // oFindPatternNode to the node-pair values. Otherwise, set
            // oParseTreeNode and oFindPatternNode both to null.

            SyntaxNode     oParseTreeNode   = null;
            SyntaxNode     oFindPatternNode = null;
            SyntaxNodePair oNodePair        =
                FindMatchingPairFromLabel(oReplacePatternNode.Label);

            if (oNodePair != null)
            {
                oParseTreeNode   = oNodePair.ParseTreeNode;
                oFindPatternNode = oNodePair.FindPatternNode;
            }

            //**************************************************************
            // If a matching node pair was not found and oReplacePatternNode
            // is optional, nothing will be copied, so return null.

            if ((oNodePair == null) && (oReplacePatternNode.IsOptionalNode))
            {
                return(null);
            }

            //**************************************************************
            // This method should only be called for leaf nodes.

            if (oParseTreeNode != null)
            {
                Debug.Assert(oParseTreeNode.IsSyntaxLeaf ||
                             oReplacePatternNode.IsSyntaxLeaf);
            }
            else
            {
                Debug.Assert(oReplacePatternNode.IsSyntaxLeaf);
            }

            //**************************************************************
            // Create a new parse-tree node by copying the features from the
            // matching oParseTreeNode (if found) and then merging the
            // features from oReplacePatternNode.

            if (VerboseDebugging)
            {
                string sParseString = "null";
                if (oParseTreeNode != null)
                {
                    sParseString = oParseTreeNode.ToString();
                }
                string sReplaceString = "null";
                if (oReplacePatternNode != null)
                {
                    sReplaceString = oReplacePatternNode.ToString();
                }
                Debug.WriteLine("Copying leaf: CopyFeatures("
                                + sParseString + "," + sReplaceString + ").");
            }

            SyntaxNode oNewNode
                = CopyFeatures(oParseTreeNode, oReplacePatternNode);

            //**************************************************************
            // Each child of a syntax leaf is the root of a morphology
            // parse. (A syntax leaf may have one or more alternative
            // morphology parses.)
            //
            // Each child will be copied recursively from oParseTreeNode.
            // Additional children will also be copied recursively from
            // oReplacePatternNode if they do not correspond to children of
            // oParseTreeNode.
            //
            // Create a list to keep track of the oReplacePatternNode
            // children as they are used. (A replace-pattern child is marked
            // as used if it has the same label as a find-pattern child
            // matching one of the oParseTreeNode children.)

            ArrayList oUsedReplaceChildren = new ArrayList();

            //**************************************************************
            // Copy the oParseTreeNode children.

            if (oParseTreeNode != null)
            {
                foreach (SyntaxNode oParseChild in
                         oParseTreeNode.ChildNodes)
                {
                    //******************************************************
                    // Look for the find-pattern node that matched this
                    // parse-tree child:
                    //
                    // Search the MatchingNodes list for a node pair where
                    // the .ParseTreeNode is the same as oParseChild.
                    //
                    // If found, set oFindChild to the .FindPatternNode
                    // value from the node pair. Otherwise, set oFindChild
                    // to null.

                    SyntaxNodePair oChildNodePair
                        = FindMatchingPairFromNode(oParseChild);
                    SyntaxNode oFindChild = null;
                    if (oChildNodePair != null)
                    {
                        oFindChild = oChildNodePair.FindPatternNode;
                    }

                    //******************************************************
                    // If oFindChild is null (no find-pattern matched
                    // this parse-tree child), copy oParseChild.
                    //
                    // Otherwise, copy each oReplacePatternNode child that
                    // has the same label as oFindChild.

                    if (oFindChild == null)
                    {
                        //**************************************************
                        // Copy oParseChild.

                        SyntaxNode oNewChild = oParseChild.CloneBranch();
                        oNewNode.ChildNodes.Add(oNewChild);
                    }
                    else
                    {
                        //**************************************************
                        // Copy each oReplacePatternNode child that has the
                        // same label as oFindChild.

                        foreach (SyntaxNode oReplaceChild in
                                 oReplacePatternNode.ChildNodes)
                        {
                            if (oReplaceChild.Label == oFindChild.Label)
                            {
                                //******************************************
                                // Copy the oReplacePatternNode child.
                                //
                                // Since oParseTreeNode is a syntax leaf,
                                // each of its children is the root of a
                                // morphology parse. So oParseChild is used
                                // as the oMorphologyParseRoot argument to
                                // the CopyNodeAndChildren() method.

                                SyntaxNode oNewChild = CopyNodeAndChildren(
                                    oReplaceChild, oParseChild);
                                if (oNewChild != null)
                                {
                                    oNewNode.ChildNodes.Add(oNewChild);
                                }

                                //******************************************
                                // Add this oReplaceChild to the list of
                                // oUsedReplaceChildren (if not already
                                // there).

                                if (!oUsedReplaceChildren
                                    .Contains(oReplaceChild))
                                {
                                    oUsedReplaceChildren.Add(oReplaceChild);
                                }
                            }
                        }
                    }
                }
            }

            //**************************************************************
            // Copy any oReplacePatternNode children that have not yet been
            // used.

            foreach (SyntaxNode oReplaceChild in
                     oReplacePatternNode.ChildNodes)
            {
                if (!oUsedReplaceChildren.Contains(oReplaceChild))
                {
                    SyntaxNode oNewChild =
                        CopyNodeAndChildren(oReplaceChild);
                    if (oNewChild != null)
                    {
                        oNewNode.ChildNodes.Add(oNewChild);
                    }
                }
            }

            //**************************************************************
            // Return the new parse-tree node after adding it to the
            // ReplacedNodes list.

            SyntaxNodeTriple oNodeTriple = new SyntaxNodeTriple();

            oNodeTriple.ParseTreeNode      = oNewNode;
            oNodeTriple.FindPatternNode    = oFindPatternNode;
            oNodeTriple.ReplacePatternNode = oReplacePatternNode;
            ReplacedNodes.Push(oNodeTriple);
            return(oNewNode);
        }
コード例 #7
0
        //******************************************************************
        /// <summary>
        /// For the given oReplacePatternNode, this method finds the
        /// corresponding find-pattern node and the parse-tree node it
        /// matched. (The parse-tree node must be in the branch indicated by
        /// oMorphologyParseRoot if this optional argument is not null.) A
        /// new node is created by copying features from the parse-tree node
        /// and merging features from the oReplacePatternNode. Then children
        /// are copied recursively either from the parse-tree node or from
        /// the oReplacePatternNode. Returns null if the oReplacePatternNode
        /// was optional and the parse-tree node was not found. Otherwise,
        /// returns the new node after adding it to the ReplacedNodes list.
        /// (Note that this method calls the CopyLeafAndChildren() method if
        /// it determines that the node is a leaf node.)
        /// </summary>
        SyntaxNode CopyNodeAndChildren(SyntaxNode oReplacePatternNode,
                                       SyntaxNode oMorphologyParseRoot)
        {
            Debug.Assert(oReplacePatternNode != null);

            //**************************************************************
            // For the given oReplacePatternNode, find the corresponding
            // find-pattern node and the parse-tree node it matched:
            //
            // Search the MatchingNodes list for a node pair where the
            // .FindPatternNode has the same label as the given
            // oReplacePatternNode.
            //
            // If oMorphologyParseRoot is not null, restrict this search to
            // node pairs where the .ParseTreeNode is contained in the
            // branch dominated by this oMorphologyParseRoot.
            //
            // If a matching node pair is found, set oParseTreeNode and
            // oFindPatternNode to the node-pair values. Otherwise, set
            // oParseTreeNode and oFindPatternNode both to null.

            SyntaxNode     oParseTreeNode   = null;
            SyntaxNode     oFindPatternNode = null;
            SyntaxNodePair oNodePair        = FindMatchingPairFromLabel(
                oReplacePatternNode.Label, oMorphologyParseRoot);

            if (oNodePair != null)
            {
                oParseTreeNode   = oNodePair.ParseTreeNode;
                oFindPatternNode = oNodePair.FindPatternNode;
            }

            //**************************************************************
            // If a matching node pair was not found and oReplacePatternNode
            // is optional, nothing will be copied, so return null.

            if ((oNodePair == null) && (oReplacePatternNode.IsOptionalNode))
            {
                return(null);
            }

            //**************************************************************
            // If this is a leaf node, call CopyLeafAndChildren() instead.
            //
            // Each child of a syntax leaf is the root of a morphology
            // parse. (A syntax leaf may have one or more alternative
            // morphology parses.) CopyLeafAndChildren() is called because
            // a different algorithm is needed to copy these children.

            bool bIsSyntaxLeaf = false;

            if (oParseTreeNode != null)
            {
                if (oParseTreeNode.IsSyntaxLeaf)
                {
                    bIsSyntaxLeaf = true;
                }
            }
            if (oReplacePatternNode.IsSyntaxLeaf)
            {
                bIsSyntaxLeaf = true;
            }
            if (bIsSyntaxLeaf)
            {
                return(CopyLeafAndChildren(oReplacePatternNode));
            }

            //**************************************************************
            // Create a new parse-tree node by copying the features from the
            // matching oParseTreeNode (if found) and then merging the
            // features from oReplacePatternNode.

            if (VerboseDebugging)
            {
                string sParseString = "null";
                if (oParseTreeNode != null)
                {
                    sParseString = oParseTreeNode.ToString();
                }
                string sReplaceString = "null";
                if (oReplacePatternNode != null)
                {
                    sReplaceString = oReplacePatternNode.ToString();
                }
                Debug.WriteLine("Copying node: CopyFeatures("
                                + sParseString + "," + sReplaceString + ").");
            }

            SyntaxNode oNewNode
                = CopyFeatures(oParseTreeNode, oReplacePatternNode);

            //**************************************************************
            // Check if any children are specified by oFindPatternNode or
            // oReplacePatternNode.

            bool bFindPatternHasChildren = false;

            if (oFindPatternNode != null)
            {
                if (oFindPatternNode.ChildNodes.Count > 0)
                {
                    bFindPatternHasChildren = true;
                }
            }
            bool bReplacePatternHasChildren = false;

            if (oReplacePatternNode.ChildNodes.Count > 0)
            {
                bReplacePatternHasChildren = true;
            }

            //**************************************************************
            // Copy children either from the matching oParseTreeNode or from
            // the oReplacePatternNode:
            //
            // If oParseTreeNode is not null and no children are specified
            // by oFindPatternNode or oReplacePatternNode, copy the
            // oParseTreeNode children.
            //
            // Otherwise, copy the oReplacePatternNode children.

            if ((oParseTreeNode != null) && (!bFindPatternHasChildren) &&
                (!bReplacePatternHasChildren))
            {
                //**********************************************************
                // Copy the oParseTreeNode children.

                foreach (SyntaxNode oParseChild in
                         oParseTreeNode.ChildNodes)
                {
                    SyntaxNode oNewChild = oParseChild.CloneBranch();
                    oNewNode.ChildNodes.Add(oNewChild);
                }
            }
            else
            {
                //**********************************************************
                // Copy the oReplacePatternNode children.

                foreach (SyntaxNode oReplaceChild in
                         oReplacePatternNode.ChildNodes)
                {
                    SyntaxNode oNewChild = CopyNodeAndChildren(
                        oReplaceChild, oMorphologyParseRoot);
                    if (oNewChild != null)
                    {
                        oNewNode.ChildNodes.Add(oNewChild);
                    }
                }
            }

            //**************************************************************
            // Return the new parse-tree node after adding it to the
            // ReplacedNodes list.

            SyntaxNodeTriple oNodeTriple = new SyntaxNodeTriple();

            oNodeTriple.ParseTreeNode      = oNewNode;
            oNodeTriple.FindPatternNode    = oFindPatternNode;
            oNodeTriple.ReplacePatternNode = oReplacePatternNode;
            ReplacedNodes.Push(oNodeTriple);
            return(oNewNode);
        }
コード例 #8
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.");
        }
コード例 #9
0
        //******************************************************************
        /// <summary>
        /// Creates a branch of SyntaxNode objects representing the nodes
        /// and features displayed by the given oTreeNode and its children
        /// (recursively). If the optional oTreeTransfer argument is given,
        /// its CurrentParseTreeNode is set to indicate the selected node
        /// (if any) in the branch, and items are added to its MatchingNodes
        /// and ReplacedNodes collections to indicate highlighted nodes in
        /// the branch. The root node of the created SyntaxNode branch is
        /// returned.
        /// </summary>
        private SyntaxNode CloneBranch(TreeViewerNode oTreeNode,
			TreeTransfer oTreeTransfer)
        {
            Debug.Assert(oTreeNode != null);
            Debug.Assert(oTreeTransfer != null);

            //**************************************************************
            // Clone the SyntaxNode branch associated with the given
            // oTreeNode.

            SyntaxNode oSyntaxNode = CloneNode(oTreeNode);

            //**************************************************************
            // The oTreeNode can have child nodes. Or the oSyntaxNode can
            // have child nodes (representing morphology nodes that were not
            // shown). But the oTreeNode and oSyntaxNode cannot both have
            // child nodes.

            if (oTreeNode.ChildNodes.Count > 0)
            {
                Debug.Assert(oSyntaxNode.ChildNodes.Count == 0);
            }
            if (oSyntaxNode.ChildNodes.Count > 0)
            {
                Debug.Assert(oTreeNode.ChildNodes.Count == 0);
            }

            //**************************************************************
            // Recursively clone each child branch of oTreeNode, and add
            // each cloned branch as a child of oSyntaxNode.

            foreach (TreeViewerNode oTreeChild in oTreeNode.ChildNodes)
            {
                SyntaxNode oSyntaxChild
                    = CloneBranch(oTreeChild,oTreeTransfer);
                oSyntaxNode.ChildNodes.Add(oSyntaxChild);
            }

            //**************************************************************
            // If this node is the SelectedNode, set the
            // oTreeTransfer.CurrentParseTreeNode property to indicate this
            // node.

            if (oTreeNode == moTreeViewer.SelectedNode)
            {
                oTreeTransfer.CurrentParseTreeNode = oSyntaxNode;
            }

            //**************************************************************
            // If this node is highlighted as a matching node, add an item
            // indicating this node to the oTreeTransfer.MatchingNodes
            // collection.
            //
            // If this node is highlighted as a replaced node, add an item
            // indicating this node to the oTreeTransfer.ReplacedNodes
            // collection.

            if ((! DisplayFindPattern) && (! DisplayReplacePattern))
            {
                if (oTreeNode.BackColor == FindPatternColor)
                {
                    SyntaxNodePair oNodePair = new SyntaxNodePair();
                    oNodePair.ParseTreeNode = oSyntaxNode;
                    oTreeTransfer.MatchingNodes.Push(oNodePair);
                }
                if (oTreeNode.BackColor == ReplacePatternColor)
                {
                    SyntaxNodeTriple oNodeTriple = new SyntaxNodeTriple();
                    oNodeTriple.ParseTreeNode = oSyntaxNode;
                    oTreeTransfer.ReplacedNodes.Push(oNodeTriple);
                }
            }

            //**************************************************************
            // Return the cloned SyntaxNode branch.

            return oSyntaxNode;
        }
コード例 #10
0
        //******************************************************************
        /// <summary>
        /// Inserts an item at the top of the stack.
        /// </summary>
        public void Push(SyntaxNodeTriple oNodeTriple)
        {
            Debug.Assert(oNodeTriple != null);

            if (oNodeTriple == null)
            {
                string sMessage = "Invalid argument: "
                    + "SyntaxNodeTripleStack cannot push a null item.";
                throw new Exception(sMessage);
            }

            InnerList.Add(oNodeTriple);
        }