//******************************************************************
        /// <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;
        }
        //******************************************************************
        /// <summary>
        /// Returns true if the indicated tree branch (dominated by oBranch)
        /// contains the given node (oNode). Returns false otherwise.
        /// </summary>
        private bool BranchContainsNode(SyntaxNode oBranch,SyntaxNode oNode)
        {
            Debug.Assert(oBranch != null);
            Debug.Assert(oNode != null);

            //**************************************************************
            // Search the branch recursively.

            if (oBranch == oNode)
            {
                return true;
            }
            foreach (SyntaxNode oChildBranch in oBranch.ChildNodes)
            {
                if (BranchContainsNode(oChildBranch,oNode))
                {
                    return true;
                }
            }
            return false;
        }
        //******************************************************************
        /// <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;
        }
        //******************************************************************
        /// <summary>
        /// Inserts the given node into the collection at the specified
        /// zero-based index, then sets the node's ParentNode property.
        /// </summary>
        public void Insert(int iIndex,SyntaxNode oNode)
        {
            //**************************************************************
            // Validate the parameters.

            Debug.Assert(iIndex >= 0);
            Debug.Assert(iIndex <= InnerList.Count);

            if (oNode == null)
            {
                string sMessage = "Invalid argument: "
                    + "SyntaxNodeCollection cannot insert a null item.";
                throw new Exception(sMessage);
            }
            if (InnerList.Contains(oNode))
            {
                string sMessage = "Invalid argument: "
                    + "SyntaxNodeCollection already contains this item.";
                throw new Exception(sMessage);
            }

            //**************************************************************
            // Insert the node into the list.

            InnerList.Insert(iIndex,oNode);

            //**************************************************************
            // Set the node's ParentNode property.

            oNode.ParentNode = ParentNode;
        }
 //******************************************************************
 /// <summary>
 /// Initializes a new instance of the SyntaxNodeCollection class,
 /// using the indicated oParentNode to set the collection's private
 /// ParentNode property, which will be used to initialize the
 /// ParentNode property of each node that is added to this
 /// collection.
 /// </summary>
 public SyntaxNodeCollection(SyntaxNode oParentNode)
 {
     moParentNode = oParentNode;
 }
Beispiel #6
0
        //******************************************************************
        /// <summary>
        /// Displays the Features form so the user can view (but not edit)
        /// the features of the given SyntaxNode. The user can also modify
        /// the FavoriteListFeatures, FavoriteTreeFeatures and
        /// CopyFavoritesOnly settings. If the user clicks OK, changes are
        /// saved to the settings, and DialogResult.OK is returned.
        /// Otherwise, DialogResult.Cancel is returned and any changes are
        /// discarded.
        /// </summary>
        public static DialogResult OpenFeaturesReadOnly(SyntaxNode oNode)
        {
            //**************************************************************
            // Validate the parameters.

            if (oNode == null)
            {
                string sMessage = "Invalid argument: "
                    + "FeaturesForm.OpenFeaturesReadOnly() requires "
                    + "a SyntaxNode object that is not null.";
                throw new Exception(sMessage);
            }

            //**************************************************************
            // Create an instance of the FeaturesForm.

            FeaturesForm oForm = new FeaturesForm();

            //**************************************************************
            // Set the form's ReadOnly property to true (the user is not
            // allowed to edit features).

            oForm.ReadOnly = true;

            //**************************************************************
            // Set the form's DisplayedNode property to a copy of the node
            // specified by the oNode parameter.

            oForm.DisplayedNode = oNode.CloneNode();

            //**************************************************************
            // Show the form so the user can view (but not edit) the
            // features of the DisplayedNode.

            DialogResult iResult = oForm.ShowDialog();

            //**************************************************************
            // Return the dialog result.

            return iResult;
        }
        //******************************************************************
        /// <summary>
        /// Returns true if the collection contains the given node. Returns
        /// false otherwise.
        /// </summary>
        public bool Contains(SyntaxNode oNode)
        {
            Debug.Assert(oNode != null);

            return InnerList.Contains(oNode);
        }
        //******************************************************************
        /// <summary>
        /// Associates the given oTreeNode with with the indicated
        /// oSyntaxNode (by setting oTreeNode.Tag to oSyntaxNode). The
        /// oSyntaxNode features are then used to determine the text that is
        /// displayed by the oTreeNode. (If this node is a leaf node and
        /// morphology nodes are not shown, the oSyntaxNode can have child
        /// nodes to represent morphology. Otherwise, the given oSyntaxNode
        /// cannot have child nodes.)
        /// </summary>
        private void PopulateNode(TreeViewerNode oTreeNode,
			SyntaxNode oSyntaxNode)
        {
            Debug.Assert(oTreeNode != null);
            Debug.Assert(oSyntaxNode != null);

            //**************************************************************
            // The oSyntaxNode can have child nodes (representing
            // morphology) only if this is a leaf node and morphology nodes
            // are not shown.

            if (! oSyntaxNode.IsSyntaxLeaf)
            {
                Debug.Assert(oSyntaxNode.ChildNodes.Count == 0);
            }
            if (ShowMorphology)
            {
                Debug.Assert(oSyntaxNode.ChildNodes.Count == 0);
            }

            //**************************************************************
            // Set the oTreeNode.Tag to associate the displayed node with
            // the indicated oSyntaxNode.

            oTreeNode.Tag = oSyntaxNode;

            //**************************************************************
            // If this is a leaf node, display the node's text in a bold
            // font style. Otherwise, use a regular font style.

            if (oSyntaxNode.IsSyntaxLeaf)
            {
                Font oFont = Font;
                if (oFont.FontFamily.IsStyleAvailable(FontStyle.Bold))
                {
                    oFont = new Font(oFont,FontStyle.Bold);
                }
                oTreeNode.Font = oFont;
            }
            else
            {
                Font oFont = Font;
                if (oFont.FontFamily.IsStyleAvailable(FontStyle.Regular))
                {
                    oFont = new Font(oFont,FontStyle.Regular);
                }
                oTreeNode.Font = oFont;
            }

            //**************************************************************
            // The displayed text always starts with the node's label.

            string sText = oSyntaxNode.Label;

            //**************************************************************
            // If the ShowFeatures property is true, add the name and value
            // text for each feature.

            if (ShowFeatures)
            {
                //**********************************************************
                // For find-pattern and replace-pattern nodes, show all
                // features.
                //
                // For parse-tree nodes, only show the features that are
                // named in the FavoriteTreeFeatures collection.

                SyntaxNode oFilteredSyntaxNode = oSyntaxNode.CloneNode();
                if ((! DisplayFindPattern) && (! DisplayReplacePattern))
                {
                    FilterFeatures(oFilteredSyntaxNode,
                        FavoriteTreeFeatures);
                }

                //**********************************************************
                // Append the name and value text for each feature (except
                // the node-label feature, since the text already starts
                // with the node's label).

                foreach (SyntaxFeature oFeature in
                    oFilteredSyntaxNode.Features)
                {
                    if (oFeature.Name != TreeTranEngineString.NodeLabel)
                    {
                        string sName = oFeature.Name;
                        string sValue = oFeature.Value;
                        sText = sText + Environment.NewLine
                            + sName + "=" + sValue;
                    }
                }
            }

            //**************************************************************
            // Set the text of the displayed node.

            oTreeNode.Text = sText;
        }
        //******************************************************************
        /// <summary>
        /// Displays the parse tree specified by the ParseTreeRoot property
        /// (or the FindPatternRoot or the DisplayPatternRoot) of the given
        /// TreeTransfer object. The TreeTransfer object also specifies the
        /// node to select (CurrentParseTreeNode property) and the nodes to
        /// highlight (in the MatchingNodes and ReplacedNodes collections).
        /// This method does not change the Modified property, raise the
        /// TreeChanged event or clear the undo information.
        /// </summary>
        private void PopulateRoot(TreeTransfer oTreeTransfer)
        {
            Debug.Assert(oTreeTransfer != null);

            //**************************************************************
            // Make a private copy of the FeaturesForm.FavoriteTreeFeatures
            // collection. This private copy will be used until the
            // PopulateRoot() method is called again, so this tree will
            // display a consistent set of features when parts of the tree
            // are edited (even if the FeaturesForm collection changes).

            FavoriteTreeFeatures.Clear();
            foreach (string sName in FeaturesForm.FavoriteTreeFeatures)
            {
                FavoriteTreeFeatures.Add(sName);
            }

            //**************************************************************
            // Call BeginUpdate() to disable redrawing the tree, but not if
            // redrawing was already disabled by the calling code.

            bool bCallEndUpdate = false;
            if (! IsUpdating)
            {
                BeginUpdate();
                bCallEndUpdate = true;
            }

            //**************************************************************
            // Get the root node that specifies the tree to display.
            //
            // Display the find-pattern tree if DisplayFindPattern is true.
            // Display the replace-pattern tree if DisplayReplacePattern is
            // true. Display the parse tree otherwise.

            SyntaxNode oSyntaxRoot = oTreeTransfer.ParseTreeRoot;
            if (DisplayFindPattern)
            {
                oSyntaxRoot = oTreeTransfer.FindPatternRoot;
            }
            if (DisplayReplacePattern)
            {
                oSyntaxRoot = oTreeTransfer.ReplacePatternRoot;
            }

            //**************************************************************
            // If the specified root node is null, display a blank node.

            if (oSyntaxRoot == null)
            {
                oSyntaxRoot = new SyntaxNode();
            }

            //**************************************************************
            // Create the root TreeViewerNode and then call PopulateBranch()
            // to display the tree.

            TreeViewerNode oTreeRoot = new TreeViewerNode();
            moTreeViewer.RootNode = oTreeRoot;
            PopulateBranch(oTreeRoot,oSyntaxRoot,oTreeTransfer);

            //**************************************************************
            // If no node is selected, select the root node.

            if (moTreeViewer.SelectedNode == null)
            {
                moTreeViewer.SelectedNode = moTreeViewer.RootNode;
            }

            //**************************************************************
            // Call EndUpdate() to redraw the tree, but not if redrawing was
            // already disabled by the calling code.

            if (bCallEndUpdate)
            {
                EndUpdate();
            }
        }
Beispiel #10
0
        //******************************************************************
        /// <summary>
        /// Uses the given oTreeNode to display features of the indicated
        /// oSyntaxNode. Children are then recursively added to oTreeNode to
        /// represent the children of oSyntaxNode (unless it is a leaf node
        /// and morphology nodes are hidden). If the optional oTreeTransfer
        /// argument is given, its CurrentParseTreeNode indicates the node
        /// to select, and items in its MatchingNodes and ReplacedNodes
        /// collections indicate nodes to highlight.
        /// </summary>
        private void PopulateBranch(TreeViewerNode oTreeNode,
			SyntaxNode oSyntaxNode)
        {
            TreeTransfer oTreeTransfer = new TreeTransfer();
            PopulateBranch(oTreeNode,oSyntaxNode,oTreeTransfer);
        }
Beispiel #11
0
        //******************************************************************
        /// <summary>
        /// Uses the given oTreeNode to display features of the indicated
        /// oSyntaxNode. Children are then recursively added to oTreeNode to
        /// represent the children of oSyntaxNode (unless it is a leaf node
        /// and morphology nodes are hidden). If the optional oTreeTransfer
        /// argument is given, its CurrentParseTreeNode indicates the node
        /// to select, and items in its MatchingNodes and ReplacedNodes
        /// collections indicate nodes to highlight.
        /// </summary>
        private void PopulateBranch(TreeViewerNode oTreeNode,
			SyntaxNode oSyntaxNode,TreeTransfer oTreeTransfer)
        {
            Debug.Assert(oTreeNode != null);
            Debug.Assert(oSyntaxNode != null);
            Debug.Assert(oTreeTransfer != null);

            //**************************************************************
            // The given oTreeNode should not already have children.

            Debug.Assert(oTreeNode.ChildNodes.Count == 0);

            //**************************************************************
            // Set the node's context menu.

            oTreeNode.ContextMenu = moMenu;

            //**************************************************************
            // Use the oTreeTransfer.CurrentParseTreeNode property to
            // determine if the node is selected.

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

            //**************************************************************
            // Use the oTreeTransfer.MatchingNodes and .ReplacedNodes
            // collections to determine the node's background color.

            Color oForeColor = SystemColors.WindowText;
            Color oBackColor = SystemColors.Window;

            foreach (SyntaxNodePair oNodePair in
                oTreeTransfer.MatchingNodes)
            {
                if (oSyntaxNode == oNodePair.ParseTreeNode)
                {
                    oBackColor = FindPatternColor;
                }
            }
            foreach (SyntaxNodeTriple oNodeTriple in
                oTreeTransfer.ReplacedNodes)
            {
                if (oSyntaxNode == oNodeTriple.ParseTreeNode)
                {
                    oBackColor = ReplacePatternColor;
                }
            }

            if (DisplayFindPattern)
            {
                oBackColor = FindPatternColor;
            }
            if (DisplayReplacePattern)
            {
                oBackColor = ReplacePatternColor;
            }

            oTreeNode.ForeColor = oForeColor;
            oTreeNode.BackColor = oBackColor;

            //**************************************************************
            // Determine if the node's children should be shown.
            //
            // A node's children are usually shown, but if the node is a
            // leaf node and ShowMorphology is false, the leaf node's
            // children (representing morphology) are not shown (unless the
            // leaf node's children are selected or highlighted).

            bool bShowChildNodes = true;
            if (oSyntaxNode.IsSyntaxLeaf)
            {
                if (! ShowMorphology)
                {
                    bShowChildNodes = false;

                    //******************************************************
                    // Even if ShowMorphology is false, a leaf node's
                    // children are shown if any of the child branches
                    // contains a selected or highlighted node.

                    foreach (SyntaxNode oSyntaxChild in
                        oSyntaxNode.ChildNodes)
                    {
                        if (BranchContainsSelectionOrHighlight(
                            oSyntaxChild,oTreeTransfer))
                        {
                            bShowChildNodes = true;
                        }
                    }
                }
            }

            //**************************************************************
            // Display the node (showing or hiding its children).

            if (bShowChildNodes)
            {
                //**********************************************************
                // Display the node and its children.
                //
                // Clone the oSyntaxNode (without including child nodes) and
                // call PopulateNode().

                PopulateNode(oTreeNode,oSyntaxNode.CloneNode());

                //**********************************************************
                // For each child node, add a new TreeViewerNode to the tree
                // and make a recursive call to PopulateBranch().

                foreach (SyntaxNode oSyntaxChild in oSyntaxNode.ChildNodes)
                {
                    TreeViewerNode oTreeChild = new TreeViewerNode();
                    oTreeNode.ChildNodes.Add(oTreeChild);
                    PopulateBranch(oTreeChild,oSyntaxChild,oTreeTransfer);
                }
            }
            else
            {
                //**********************************************************
                // Display the node, but hide its children.
                //
                // Clone the entire oSyntaxNode branch (so the cloned branch
                // includes child nodes that represent morphology) and call
                // PopulateNode().

                PopulateNode(oTreeNode,oSyntaxNode.CloneBranch());
            }
        }
Beispiel #12
0
        //******************************************************************
        /// <summary>
        /// Recursively traverses the tree dominated by the indicated
        /// oSyntaxNode, removing all node features with names that do not
        /// appear in the given oFeatureNames collection.
        /// </summary>
        private void FilterFeatures(SyntaxNode oSyntaxNode,
			StringCollection oFeatureNames)
        {
            Debug.Assert(oSyntaxNode != null);
            Debug.Assert(oFeatureNames != null);

            //**************************************************************
            // Create a filtered-features collection.

            SyntaxFeatureCollection oFilteredFeatures
                = new SyntaxFeatureCollection();

            //**************************************************************
            // Always copy the node's label feature to the filtered-features
            // collection.

            oFilteredFeatures[TreeTranEngineString.NodeLabel]
                = oSyntaxNode.Label;

            //**************************************************************
            // For each feature name in the oFeatureNames collection, copy
            // the named feature (if it exists) from the node to the
            // filtered-features collection. (The features are copied in the
            // same order that the names appear in oFeaturesNames.)

            foreach (string sName in oFeatureNames)
            {
                if (oSyntaxNode.Features.Contains(sName))
                {
                    string sValue = oSyntaxNode.Features[sName];
                    oFilteredFeatures[sName] = sValue;
                }
            }

            //**************************************************************
            // Clear the node's features, and then copy all the features
            // from the filtered-features collection back to the node.

            oSyntaxNode.Features.Clear();
            foreach (SyntaxFeature oFeature in oFilteredFeatures)
            {
                string sName = oFeature.Name;
                string sValue = oFeature.Value;
                oSyntaxNode.Features[sName] = sValue;
            }

            //**************************************************************
            // Recursively traverse each child branch, filtering features.

            foreach (SyntaxNode oSyntaxChild in oSyntaxNode.ChildNodes)
            {
                FilterFeatures(oSyntaxChild,oFeatureNames);
            }
        }
 //******************************************************************
 #region [Constructor]
 //******************************************************************
 /// <summary>
 /// Initializes a new instance of the SyntaxNodeCollection class,
 /// using the indicated oParentNode to set the collection's private
 /// ParentNode property, which will be used to initialize the
 /// ParentNode property of each node that is added to this
 /// collection.
 /// </summary>
 public SyntaxNodeCollection(SyntaxNode oParentNode)
 {
     moParentNode = oParentNode;
 }
        //******************************************************************
        /// <summary>
        /// Searches the collection for the given node. Returns the node's
        /// zero-based index if it was found. Returns -1 otherwise.
        /// </summary>
        public int IndexOf(SyntaxNode oNode)
        {
            Debug.Assert(oNode != null);

            return(InnerList.IndexOf(oNode));
        }
        //******************************************************************
        /// <summary>
        /// Searches the MatchingNodes list for a node pair where the
        /// .ParseTreeNode is the same as the given oParseTreeNode. Returns
        /// the first matching node pair, if a match is found. Returns null
        /// otherwise.
        /// </summary>
        private SyntaxNodePair FindMatchingPairFromNode(
			SyntaxNode oParseTreeNode)
        {
            Debug.Assert(oParseTreeNode != null);

            //**************************************************************
            // Search the MatchingNodes list for a node pair where the
            // .ParseTreeNode is the same as the given oParseTreeNode.
            // Return the (first) matching node pair if found.

            foreach (SyntaxNodePair oPair in MatchingNodes)
            {
                Debug.Assert(oPair.ParseTreeNode != null);
                Debug.Assert(oPair.FindPatternNode != null);

                if (oPair.ParseTreeNode == oParseTreeNode)
                {
                    return oPair;
                }
            }

            //**************************************************************
            // Return null if a match was not found.

            return null;
        }
Beispiel #16
0
        //******************************************************************
        /// <summary>
        /// Recursively traverses the tree dominated by the indicated
        /// oSyntaxNode, making sure each node has a label that is not
        /// already in the given oLabelsInUse collection. If necessary, node
        /// labels are renamed to make them unique. Each node label is added
        /// to the oLabelsInUse collection as nodes are traversed.
        /// </summary>
        private void RenameLabelsInUse(SyntaxNode oSyntaxNode,
			StringCollection oLabelsInUse)
        {
            Debug.Assert(oSyntaxNode != null);
            Debug.Assert(oLabelsInUse != null);

            //**************************************************************
            // Check if the node's label already exists in the oLabelsInUse
            // collection. If so, change the label to a new string
            // consisting of the node's category string followed by the "#"
            // character and a number (for example: "NP#2"). Keep
            // incrementing the number, until the node's label is not found
            // in the oLabelsInUse collection.

            int iNumber = 1;
            while (oLabelsInUse.Contains(oSyntaxNode.Label))
            {
                ++iNumber;
                string sLabel = oSyntaxNode.Category
                    + "#" + iNumber.ToString();
                if (oSyntaxNode.IsOptionalNode)
                {
                    //******************************************************
                    // If the node is optional, make sure its new label
                    // indicates that it is optional by enclosing the new
                    // label string in parenthesis (for example: "(NP#2)").

                    sLabel = TreeTranEngineString.LeftParenthesis + sLabel
                        + TreeTranEngineString.RightParenthesis;
                }
                oSyntaxNode.Features[TreeTranEngineString.NodeLabel]
                    = sLabel;
            }

            //**************************************************************
            // Add the node's label to the oLabelsInUse collection.

            oLabelsInUse.Add(oSyntaxNode.Label);

            //**************************************************************
            // Recursively traverse each child branch.

            foreach (SyntaxNode oSyntaxChild in oSyntaxNode.ChildNodes)
            {
                RenameLabelsInUse(oSyntaxChild,oLabelsInUse);
            }
        }
        //******************************************************************
        /// <summary>
        /// Returns true if the collection contains the given node. Returns
        /// false otherwise.
        /// </summary>
        public bool Contains(SyntaxNode oNode)
        {
            Debug.Assert(oNode != null);

            return(InnerList.Contains(oNode));
        }
Beispiel #18
0
        //******************************************************************
        /// <summary>
        /// Copies the current selection to the clipboard.
        /// </summary>
        public void Copy()
        {
            //**************************************************************
            // Validate the current state.

            if (! CanCopy())
            {
                string sMessage = "Invalid state: "
                    + "A call to ParseTreeViewer.Copy() is not allowed "
                    + "if ParseTreeViewer.CanCopy() returns false.";
                throw new Exception(sMessage);
            }

            //**************************************************************
            // Clone the selected branch. If no branch is selected, clone
            // the whole tree. (As a last result, use an empty node.)

            SyntaxNode oSyntaxBranchToCopy = null;
            if (moTreeViewer.SelectedNode != null)
            {
                oSyntaxBranchToCopy
                    = CloneBranch(moTreeViewer.SelectedNode);
            }
            if (oSyntaxBranchToCopy == null)
            {
                oSyntaxBranchToCopy = CloneTree();
            }
            if (oSyntaxBranchToCopy == null)
            {
                oSyntaxBranchToCopy = new SyntaxNode();
            }

            //**************************************************************
            // If the CopyFavoritesOnly option is true and we are copying
            // from a parse tree (not a find pattern or replace pattern),
            // filter out any features that are not named in the
            // FavoriteListFeatures collection.

            if (FeaturesForm.CopyFavoritesOnly)
            {
                if ((! DisplayFindPattern) && (! DisplayReplacePattern))
                {
                    FilterFeatures(oSyntaxBranchToCopy,
                        FeaturesForm.FavoriteListFeatures);
                }
            }

            //**************************************************************
            // Create a RuleWriter that writes to a string.

            StringBuilder oStringBuilder = new StringBuilder();
            TextWriter oTextWriter = new StringWriter(oStringBuilder);
            RuleWriter oRuleWriter = new RuleWriter(oTextWriter);

            //**************************************************************
            // Make a rule that uses the indicated branch as its find
            // pattern (and has an empty replace pattern).

            oRuleWriter.RuleName = "(tree fragment on clipboard)";
            oRuleWriter.FindPatternRoot = oSyntaxBranchToCopy;
            oRuleWriter.ReplacePatternRoot = null;

            //**************************************************************
            // Write the rule to the string.

            oRuleWriter.Write();

            //**************************************************************
            // Close the RuleWriter.

            oRuleWriter.Close();

            //**************************************************************
            // Copy the string to the clipboard.

            const bool bCopy = true;
            Clipboard.SetDataObject(oStringBuilder.ToString(),bCopy);
        }
        //******************************************************************
        /// <summary>
        /// Adds the given node to the end of the collection, then sets the
        /// node's ParentNode property. Returns the zero-based index of the
        /// added node.
        /// </summary>
        public int Add(SyntaxNode oNode)
        {
            Debug.Assert(oNode != null);
            Debug.Assert(! InnerList.Contains(oNode));

            int iIndex = Count;
            Insert(iIndex,oNode);
            return iIndex;
        }
Beispiel #20
0
        //******************************************************************
        /// <summary>
        /// Deletes the current selection.
        /// </summary>
        public void Delete()
        {
            //**************************************************************
            // Validate the current state.

            if (! CanDelete())
            {
                string sMessage = "Invalid state: "
                    + "A call to ParseTreeViewer.Delete() is not allowed "
                    + "if ParseTreeViewer.CanDelete() returns false.";
                throw new Exception(sMessage);
            }

            //**************************************************************
            // Prevent modification to a read-only tree.

            if (ReadOnly)
            {
                return;
            }

            //**************************************************************
            // Use the current contents of the tree (before the delete
            // operation) to set the undo information.

            TreeTransferForUndo = RecreateTreeTransfer();

            //**************************************************************
            // Call BeginUpdate() to disable redrawing the tree, but not if
            // redrawing was already disabled by the calling code.

            bool bCallEndUpdate = false;
            if (! IsUpdating)
            {
                BeginUpdate();
                bCallEndUpdate = true;
            }

            //**************************************************************
            // Delete the branch dominated by the selected node.

            if (moTreeViewer.SelectedNode != null)
            {
                if (moTreeViewer.SelectedNode == moTreeViewer.RootNode)
                {
                    //******************************************************
                    // The selected node is the root node.
                    //
                    // Replace the root node with an empty node. Select the
                    // new root node.

                    moTreeViewer.RootNode = new TreeViewerNode();
                    SyntaxNode oSyntaxNode = new SyntaxNode();
                    PopulateBranch(moTreeViewer.RootNode,oSyntaxNode);
                    moTreeViewer.SelectedNode = moTreeViewer.RootNode;
                }
                else
                {
                    //******************************************************
                    // The selected node is not the root node.
                    //
                    // Remove the selected node. Select the parent of the
                    // removed node.

                    TreeViewerNode oTreeParent
                        = moTreeViewer.SelectedNode.ParentNode;
                    if (oTreeParent != null)
                    {
                        oTreeParent.ChildNodes
                            .Remove(moTreeViewer.SelectedNode);
                        moTreeViewer.SelectedNode = oTreeParent;
                    }
                }
            }

            //**************************************************************
            // Call EndUpdate() to redraw the tree, but not if redrawing was
            // already disabled by the calling code.

            if (bCallEndUpdate)
            {
                EndUpdate();
            }

            //**************************************************************
            // Set the Modified property to true and raise the TreeChanged
            // event.

            Modified = true;
            OnTreeChanged(new EventArgs());
        }
        //******************************************************************
        /// <summary>
        /// Searches the collection for the given node. Returns the node's
        /// zero-based index if it was found. Returns -1 otherwise.
        /// </summary>
        public int IndexOf(SyntaxNode oNode)
        {
            Debug.Assert(oNode != null);

            return InnerList.IndexOf(oNode);
        }
Beispiel #22
0
        //******************************************************************
        /// <summary>
        /// Saves the displayed rules to the indicated rule file
        /// (sFileName). The Modified property is set to false after the
        /// file is saved.
        /// </summary>
        public void SaveRuleFile(string sFileName)
        {
            //**************************************************************
            // Validate the parameters.

            if ((sFileName == null) || (sFileName == ""))
            {
                string sMessage = "Invalid argument: "
                    + "RuleListViewer.SaveRuleFile() requires "
                    + "a file name that is not null or blank.";
                throw new Exception(sMessage);
            }

            //**************************************************************
            // Create a RuleWriter to write to the indicated rule file.

            StreamWriter oStreamWriter = new StreamWriter(sFileName);
            RuleWriter oRuleWriter = new RuleWriter(oStreamWriter);

            //**************************************************************
            // For each item in the ListView, write the rule to the file.

            foreach (ListViewItem oItem in moListView.Items)
            {
                //**********************************************************
                // Get the rule from the ListView item.

                Debug.Assert(oItem is RuleListViewerItem);

                RuleListViewerItem oRuleItem = (RuleListViewerItem) oItem;

                //**********************************************************
                // Make sure the find pattern is not null.

                SyntaxNode oFindPatternRoot
                    = oRuleItem.FindPatternRoot;
                if (oFindPatternRoot == null)
                {
                    oFindPatternRoot = new SyntaxNode();
                }

                //**********************************************************
                // Make sure the replace pattern is not null.

                SyntaxNode oReplacePatternRoot
                    = oRuleItem.ReplacePatternRoot;
                if (oReplacePatternRoot == null)
                {
                    oReplacePatternRoot = new SyntaxNode();
                }

                //**********************************************************
                // Write the rule to the file.

                oRuleWriter.RuleName = oRuleItem.Text;
                oRuleWriter.FindPatternRoot = oFindPatternRoot;
                oRuleWriter.ReplacePatternRoot = oReplacePatternRoot;
                oRuleWriter.Write();
            }

            //**************************************************************
            // Close the RuleWriter.

            oRuleWriter.Close();

            //**************************************************************
            // Set the Modified property to false.

            Modified = false;
        }
        //******************************************************************
        /// <summary>
        /// Removes the given node from the collection, after recursively
        /// clearing the children of the removed node.
        /// </summary>
        public void Remove(SyntaxNode oNode)
        {
            Debug.Assert(oNode != null);
            Debug.Assert(InnerList.Contains(oNode));

            //**************************************************************
            // Recursively clear the children of the indicated node.

            oNode.ChildNodes.Clear();

            //**************************************************************
            // Remove the indicated node.

            InnerList.Remove(oNode);

            //**************************************************************
            // Set the parent of the removed node to null.

            oNode.ParentNode = null;
        }
Beispiel #24
0
        //******************************************************************
        /// <summary>
        /// Copies the current selection to the clipboard.
        /// </summary>
        public void Copy()
        {
            //**************************************************************
            // Validate the current state.

            if (! CanCopy())
            {
                string sMessage = "Invalid state: "
                    + "A call to RuleListViewer.Copy() is not allowed "
                    + "if RuleListViewer.CanCopy() returns false.";
                throw new Exception(sMessage);
            }

            //**************************************************************
            // Create a RuleWriter that writes to a string.

            StringBuilder oStringBuilder = new StringBuilder();
            TextWriter oTextWriter = new StringWriter(oStringBuilder);
            RuleWriter oRuleWriter = new RuleWriter(oTextWriter);

            //**************************************************************
            // Write each selected rule to the string.

            foreach (ListViewItem oItem in moListView.Items)
            {
                //**********************************************************
                // Get the rule from the ListView item.

                Debug.Assert(oItem is RuleListViewerItem);

                RuleListViewerItem oRuleItem = (RuleListViewerItem) oItem;

                //**********************************************************
                // If the item is selected, write the rule to the string.

                if (oRuleItem.Selected)
                {
                    //******************************************************
                    // Make sure the find pattern is not null.

                    SyntaxNode oFindPatternRoot
                        = oRuleItem.FindPatternRoot;
                    if (oFindPatternRoot == null)
                    {
                        oFindPatternRoot = new SyntaxNode();
                    }

                    //******************************************************
                    // Make sure the replace pattern is not null.

                    SyntaxNode oReplacePatternRoot
                        = oRuleItem.ReplacePatternRoot;
                    if (oReplacePatternRoot == null)
                    {
                        oReplacePatternRoot = new SyntaxNode();
                    }

                    //******************************************************
                    // Write the rule to the string.

                    oRuleWriter.RuleName = oRuleItem.Text;
                    oRuleWriter.FindPatternRoot = oFindPatternRoot;
                    oRuleWriter.ReplacePatternRoot = oReplacePatternRoot;
                    oRuleWriter.Write();
                }
            }

            //**************************************************************
            // Close the RuleWriter.

            oRuleWriter.Close();

            //**************************************************************
            // Copy the string to the clipboard.

            const bool bCopy = true;
            Clipboard.SetDataObject(oStringBuilder.ToString(),bCopy);
        }
        //******************************************************************
        /// <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.");
        }
Beispiel #26
0
        //******************************************************************
        /// <summary>
        /// Copies the current selection to the clipboard.
        /// </summary>
        public void Copy()
        {
            //**************************************************************
            // Validate the current state.

            if (! CanCopy())
            {
                string sMessage = "Invalid state: "
                    + "A call to ParseListViewer.Copy() is not allowed "
                    + "if ParseListViewer.CanCopy() returns false.";
                throw new Exception(sMessage);
            }

            //**************************************************************
            // Create a RuleWriter that writes to a string.

            StringBuilder oStringBuilder = new StringBuilder();
            TextWriter oTextWriter = new StringWriter(oStringBuilder);
            RuleWriter oRuleWriter = new RuleWriter(oTextWriter);

            //**************************************************************
            // Write each selected parse to the string.

            foreach (ListViewItem oItem in moListView.Items)
            {
                //**********************************************************
                // Get the parse from the ListView item.

                Debug.Assert(oItem is ParseListViewerItem);

                ParseListViewerItem oParseItem
                    = (ParseListViewerItem) oItem;

                //**********************************************************
                // If the item is selected, write the parse to the string.

                if (oParseItem.Selected)
                {
                    //******************************************************
                    // Make sure the parse tree is not null.

                    SyntaxNode oParseTreeRoot = oParseItem.ParseTreeRoot;
                    if (oParseTreeRoot == null)
                    {
                        oParseTreeRoot = new SyntaxNode();
                    }

                    //******************************************************
                    // Write the parse tree to the string.
                    //
                    // The parse tree is written in the format of a transfer
                    // rule: the .RuleName is the item's displayed text, the
                    // .FindPatternRoot is the parse tree, and the
                    // .ReplacePatternRoot is null.

                    oRuleWriter.RuleName = oParseItem.Text;
                    oRuleWriter.FindPatternRoot = oParseTreeRoot;
                    oRuleWriter.ReplacePatternRoot = null;
                    oRuleWriter.Write();
                }
            }

            //**************************************************************
            // Close the RuleWriter.

            oRuleWriter.Close();

            //**************************************************************
            // Copy the string to the clipboard.

            const bool bCopy = true;
            Clipboard.SetDataObject(oStringBuilder.ToString(),bCopy);
        }
        //******************************************************************
        /// <summary>
        /// Creates a new parse-tree node. Features are copied from the
        /// given oParseTreeNode (if not null). Then features are merged
        /// from the given oReplacePatternNode (if not null). Returns the
        /// new parse-tree node.
        /// </summary>
        private SyntaxNode CopyFeatures(SyntaxNode oParseTreeNode,
			SyntaxNode oReplacePatternNode)
        {
            Debug.Assert((oParseTreeNode != null)
                || (oReplacePatternNode != null));

            //**************************************************************
            // Create a new SyntaxNode.

            SyntaxNode oNewNode = new SyntaxNode();

            //**************************************************************
            // Copy all the features from oParseTreeNode (if not null).

            if (oParseTreeNode != null)
            {
                foreach (SyntaxFeature oFeature in oParseTreeNode.Features)
                {
                    oNewNode.Features[oFeature.Name] = oFeature.Value;
                }
            }

            //**************************************************************
            // Merge the features from oReplacePatternNode (if not null):
            //
            // Copy each feature from oReplacePatternNode, except for the
            // node-label feature. (Copied features will replace existing
            // features with the same name.)
            //
            // If a feature from oReplacePatternNode has the delete-feature
            // string for its value, delete the feature from the new node.

            if (oReplacePatternNode != null)
            {
                foreach (SyntaxFeature oFeature in
                    oReplacePatternNode.Features)
                {
                    if (oFeature.Name != TreeTranEngineString.NodeLabel)
                    {
                        oNewNode.Features[oFeature.Name] = oFeature.Value;
                    }
                    if (oFeature.Value
                        == TreeTranEngineString.DeleteFeature)
                    {
                        oNewNode.Features.Remove(oFeature.Name);
                    }
                }
            }

            //**************************************************************
            // Return the new SyntaxNode.

            return oNewNode;
        }
Beispiel #28
0
        //******************************************************************
        /// <summary>
        /// Saves the displayed parses to the indicated parse file
        /// (sFileName). The Modified property is set to false after the
        /// file is saved.
        /// </summary>
        public void SaveParseFile(string sFileName)
        {
            //**************************************************************
            // Validate the parameters.

            if ((sFileName == null) || (sFileName == ""))
            {
                string sMessage = "Invalid argument: "
                    + "ParseListViewer.SaveParseFile() requires "
                    + "a file name that is not null or blank.";
                throw new Exception(sMessage);
            }

            //**************************************************************
            // Create a ParseWriter to write to the indicated parse file.

            StreamWriter oStreamWriter = new StreamWriter(sFileName);
            ParseWriter oParseWriter = new ParseWriter(oStreamWriter);

            //**************************************************************
            // For each item in the ListView, write the parse to the file.

            foreach (ListViewItem oItem in moListView.Items)
            {
                //**********************************************************
                // Get the parse from the ListView item.

                Debug.Assert(oItem is ParseListViewerItem);

                ParseListViewerItem oParseItem
                    = (ParseListViewerItem) oItem;

                //**********************************************************
                // Make sure the parse tree is not null.

                SyntaxNode oParseTreeRoot = oParseItem.ParseTreeRoot;
                if (oParseTreeRoot == null)
                {
                    oParseTreeRoot = new SyntaxNode();
                }

                //**********************************************************
                // Write the parse tree to the file.

                oParseWriter.ParseTreeRoot = oParseTreeRoot;
                oParseWriter.Write();
            }

            //**************************************************************
            // Close the ParseWriter.

            oParseWriter.Close();

            //**************************************************************
            // Set the Modified property to false.

            Modified = false;
        }
 //******************************************************************
 /// <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)
 {
     return CopyNodeAndChildren(oReplacePatternNode,null);
 }
Beispiel #30
0
        //******************************************************************
        /// <summary>
        /// Copies the selected features from the ListView to the clipboard.
        /// </summary>
        private void CopySelectedFeatures()
        {
            //**************************************************************
            // Create a SyntaxNode and set its features by copying the
            // selected feature names and values from the ListView.
            //
            // (Do not copy blank features, which can appear when the
            // show-all-favorites option is checked.)

            SyntaxNode oNode = new SyntaxNode();
            foreach (ListViewItem oItem in moListView.SelectedItems)
            {
                string sName = oItem.SubItems[moNameColumn.Index].Text;
                string sValue = oItem.SubItems[moValueColumn.Index].Text;
                if ((sName != "") && (sValue != ""))
                {
                    oNode.Features[sName] = sValue;
                }
            }

            //**************************************************************
            // Create a RuleWriter that writes to a string.

            StringBuilder oStringBuilder = new StringBuilder();
            TextWriter oTextWriter = new StringWriter(oStringBuilder);
            RuleWriter oRuleWriter = new RuleWriter(oTextWriter);

            //**************************************************************
            // Make a rule that uses the SyntaxNode with the selected
            // features as its find pattern (and has an empty replace
            // pattern).

            oRuleWriter.RuleName = "(tree fragment on clipboard)";
            oRuleWriter.FindPatternRoot = oNode;
            oRuleWriter.ReplacePatternRoot = null;

            //**************************************************************
            // Write the rule to the string.

            oRuleWriter.Write();

            //**************************************************************
            // Close the RuleWriter.

            oRuleWriter.Close();

            //**************************************************************
            // Copy the string to the clipboard.

            const bool bCopy = true;
            Clipboard.SetDataObject(oStringBuilder.ToString(),bCopy);
        }
        //******************************************************************
        /// <summary>
        /// Searches the MatchingNodes list for a node pair where the
        /// .FindPatternNode label matches the given sLabel string. If the
        /// optional oMorphologyParseRoot argument is not null, the search
        /// is restricted to node pairs where the .ParseTreeNode is
        /// contained in the branch dominated by the oMorphologyParseRoot
        /// node. Returns the first matching node pair, if a match is found.
        /// Returns null otherwise.
        /// </summary>
        private SyntaxNodePair FindMatchingPairFromLabel(string sLabel,
			SyntaxNode oMorphologyParseRoot)
        {
            Debug.Assert(sLabel != null);

            //**************************************************************
            // Check if a oMorphologyParseRoot is specified.

            if (oMorphologyParseRoot != null)
            {
                //**********************************************************
                // If a oMorphologyParseRoot is specified, search the
                // MatchingNodes list for a node pair where the
                // .FindPatternNode label matches the sLabel string and the
                // .ParseTreeNode is contained in the parse-tree branch
                // dominated by oMorphologyParseRoot. Return the (first)
                // matching node pair if found.

                foreach (SyntaxNodePair oPair in MatchingNodes)
                {
                    Debug.Assert(oPair.ParseTreeNode != null);
                    Debug.Assert(oPair.FindPatternNode != null);

                    if (oPair.FindPatternNode.Label == sLabel)
                    {
                        if (BranchContainsNode(oMorphologyParseRoot,
                            oPair.ParseTreeNode))
                        {
                            return oPair;
                        }
                    }
                }
            }
            else
            {
                //**********************************************************
                // Otherwise, search the MatchingNodes list for any node
                // pair where the .FindPatternNode label matches the sLabel
                // string. Return the (first) matching node pair if found.

                foreach (SyntaxNodePair oPair in MatchingNodes)
                {
                    Debug.Assert(oPair.ParseTreeNode != null);
                    Debug.Assert(oPair.FindPatternNode != null);

                    if (oPair.FindPatternNode.Label == sLabel)
                    {
                        return oPair;
                    }
                }
            }

            //**************************************************************
            // Return null if a match was not found.

            return null;
        }
Beispiel #32
0
        //******************************************************************
        /// <summary>
        /// Displays the Features form so the user can view and edit the
        /// features of the given SyntaxNode. The user can also modify the
        /// FavoriteListFeatures, FavoriteTreeFeatures and CopyFavoritesOnly
        /// settings. If the user clicks OK, the edits are saved to the
        /// SyntaxNode features, changes are saved to the settings, and
        /// DialogResult.OK is returned. Otherwise, DialogResult.Cancel is
        /// returned and any changes are discarded.
        /// </summary>
        public static DialogResult OpenFeatures(SyntaxNode oNode)
        {
            //**************************************************************
            // Validate the parameters.

            if (oNode == null)
            {
                string sMessage = "Invalid argument: "
                    + "FeaturesForm.OpenFeatures() requires "
                    + "a SyntaxNode object that is not null.";
                throw new Exception(sMessage);
            }

            //**************************************************************
            // Create an instance of the FeaturesForm.

            FeaturesForm oForm = new FeaturesForm();

            //**************************************************************
            // Set the form's ReadOnly property to false.

            oForm.ReadOnly = false;

            //**************************************************************
            // Set the form's DisplayedNode property to a copy of the node
            // specified by the oNode parameter.

            oForm.DisplayedNode = oNode.CloneNode();

            //**************************************************************
            // Show the form so the user can view and edit the features of
            // the DisplayedNode.

            DialogResult iResult = oForm.ShowDialog();

            //**************************************************************
            // If the user clicked OK, save the changes that the user made
            // to the features:
            //
            // Update the specified oNode by clearing its features and then
            // copying all the features from the form's DisplayedNode to the
            // oNode.Features collection.

            if (iResult == DialogResult.OK)
            {
                oNode.Features.Clear();
                foreach (SyntaxFeature oFeature in
                    oForm.DisplayedNode.Features)
                {
                    oNode.Features[oFeature.Name] = oFeature.Value;
                }
            }

            //**************************************************************
            // Return the dialog result.

            return iResult;
        }
Beispiel #33
0
        //******************************************************************
        /// <summary>
        /// Recursively traverses the indicated branch (dominiated by oNode)
        /// of the find-pattern tree or replace-pattern tree, writing the
        /// nodes and their features.
        /// </summary>
        private void WriteNode(SyntaxNode oNode)
        {
            //**************************************************************
            // Write the opening <Node> tag:
            //
            // <Node>

            Writer.WriteStartElement(RuleXml.NodeElement);

            //**************************************************************
            // Write the node features.

            foreach (SyntaxFeature oFeature in oNode.Features)
            {
                //**************************************************************
                // Write the <Feature> tag:
                //
                // <Feature name="..." value="..." />
                //
                // The "name" attribute represents the feature Name.
                //
                // The "value" attribute represents the feature Value.

                Writer.WriteStartElement(RuleXml.FeatureElement);
                Writer.WriteAttributeString(RuleXml.NameAttribute,
                    oFeature.Name);
                Writer.WriteAttributeString(RuleXml.ValueAttribute,
                    oFeature.Value);
                Writer.WriteEndElement();
            }

            //**************************************************************
            // Write the child nodes.

            foreach (SyntaxNode oChild in oNode.ChildNodes)
            {
                WriteNode(oChild);
            }

            //**************************************************************
            // Write the closing <Node> tag:
            //
            // </Node>

            Writer.WriteEndElement();
        }
Beispiel #34
0
        //******************************************************************
        #region [FindNextMatchingBranch() Method]
        //******************************************************************
        /// <summary>
        /// Moves the CurrentParseTreeNode forward in the parse tree, until
        /// the sub-tree dominated by this node matches the pattern
        /// dominated by FindPatternRoot. If CurrentParseTreeNode is null
        /// when this method is called, the search starts with the first
        /// node in the parse tree. Otherwise, the search continues with the
        /// next node in the tree. If a matching sub-tree is found, true is
        /// returned and the MatchingNodes stack contains the list of
        /// matching node pairs. If no match is found, CurrentParseTreeNode
        /// is set to null and false is returned.
        /// </summary>
        public bool FindNextMatchingBranch()
        {
            Debug.WriteLineIf(VerboseDebugging,
                              "FindAlgorithm.FindNextMatchingBranch() called.");

            //**************************************************************
            // Validate the current state.

            if (CurrentParseTreeNode != null)
            {
                SyntaxNode oNode = CurrentParseTreeNode;
                while (oNode != ParseTreeRoot)
                {
                    if (oNode.ParentNode == null)
                    {
                        string sMessage = "FindNextMatchingBranch() "
                                          + "called with an invalid state: "
                                          + "the ParseTreeRoot tree does not contain "
                                          + "the CurrentParseTreeNode.";
                        throw new Exception(sMessage);
                    }
                    oNode = oNode.ParentNode;
                }
            }

            //**************************************************************
            // Clear the lists of MatchingNodes and ReplacedNodes.

            MatchingNodes.Clear();
            ReplacedNodes.Clear();

            //**************************************************************
            // Save the previous value of the CurrentParseTreeNode.

            SyntaxNode oPreviousParseTreeNode = CurrentParseTreeNode;

            //**************************************************************
            // Move the CurrentParseTreeNode to the next branch to compare:
            //
            //     If CurrentParseTreeNode is null, start with the first
            //     parse-tree node in post order.
            //
            //     Otherwise, move to the next node in post order.
            //
            // Note: The parse tree is traversed in post-order (parent after
            // its children) to prevent infinite recursion that could occur
            // if an XP node was replaced by a node with XP children, and
            // then the rule was applied recursively to these children.

            if (CurrentParseTreeNode == null)
            {
                CurrentParseTreeNode
                    = GetFirstNodeInPostOrder(ParseTreeRoot);
            }
            else
            {
                CurrentParseTreeNode
                    = GetNextNodeInPostOrder(CurrentParseTreeNode);
            }

            //**************************************************************
            // Check if the previous branch should be deleted.
            //
            // When the ReplaceCurrentMatchingBranch() method needs to
            // delete the current parse-tree node, it sets it to an empty
            // node (one with no features and no children) instead. This is
            // so we can use the current parse-tree node to determine where
            // to find the next node to compare.
            //
            // If the previous branch is an empty node (with no features and
            // no children), delete it.

            if (oPreviousParseTreeNode != null)
            {
                if ((oPreviousParseTreeNode.Features.Count == 0) &&
                    (oPreviousParseTreeNode.ChildNodes.Count == 0))
                {
                    //******************************************************
                    // Remove the empty node from its parent's ChildNodes
                    // collection. If the empty node is the same as the
                    // ParseTreeRoot, set the ParseTreeRoot to null.

                    SyntaxNode oParent = oPreviousParseTreeNode.ParentNode;
                    if (oParent != null)
                    {
                        oParent.ChildNodes.Remove(oPreviousParseTreeNode);
                    }
                    if (oPreviousParseTreeNode == ParseTreeRoot)
                    {
                        ParseTreeRoot = null;
                    }
                }
            }

            //**************************************************************
            // If FindPatternRoot is null, nothing can match this pattern.
            // In this case, set CurrentParseTreeNode to null so there will
            // be no comparisons and false will be returned.

            if (FindPatternRoot == null)
            {
                CurrentParseTreeNode = null;
            }

            //**************************************************************
            // Traverse the parse tree (in post order), looking for a match,
            // until there are no more nodes to traverse. Return true if a
            // match is found.

            while (CurrentParseTreeNode != null)
            {
                //**********************************************************
                // Return true if the current branch matches the pattern.

                if (CurrentBranchMatchesPattern())
                {
                    Debug.Assert(MatchingNodes.Count > 0);
                    Debug.Assert(ReplacedNodes.Count == 0);
                    Debug.Assert(CurrentParseTreeNode != null);

                    Debug.WriteLineIf(VerboseDebugging,
                                      "FindAlgorithm.FindNextMatchingBranch() returns "
                                      + "true.");

                    return(true);
                }

                //**********************************************************
                // Move to the next node in post order.

                CurrentParseTreeNode
                    = GetNextNodeInPostOrder(CurrentParseTreeNode);
            }

            //**************************************************************
            // A matching branch was not found, so return false.

            Debug.Assert(MatchingNodes.Count == 0);
            Debug.Assert(ReplacedNodes.Count == 0);
            Debug.Assert(CurrentParseTreeNode == null);

            Debug.WriteLineIf(VerboseDebugging,
                              "FindAlgorithm.FindNextMatchingBranch() returns false.");

            return(false);
        }