コード例 #1
0
        /// <summary>
        /// Removes useless symbols from the grammar.
        /// Assumes that the language is nonempty.
        /// </summary>
        public ContextFreeGrammar RemoveUselessSymbols()
        {
            HashSet <Nonterminal> useful_backwards = new HashSet <Nonterminal>();

            //Lemma 4.1, p. 88, Hopcroft-Ullman
            #region backward reachability
            var variableNodeMap = new Dictionary <Nonterminal, VariableNode>();
            foreach (Nonterminal v in this.variables)
            {
                variableNodeMap[v] = new VariableNode();
            }


            List <ProductionNode> productionLeaves = new List <ProductionNode>();

            foreach (Nonterminal v in this.variables)
            {
                VariableNode parent = variableNodeMap[v];
                foreach (Production p in this.productionMap[v])
                {
                    var            children = Array.ConvertAll(new List <Nonterminal>(p.GetVariables()).ToArray(), w => variableNodeMap[w]);
                    ProductionNode pn       = new ProductionNode(parent, children);
                    if (children.Length == 0)
                    {
                        productionLeaves.Add(pn);
                    }
                    else
                    {
                        foreach (VariableNode child in children)
                        {
                            child.parents.Add(pn);
                        }
                    }
                }
            }

            foreach (ProductionNode leaf in productionLeaves)
            {
                leaf.PropagateMark();
            }

            foreach (Nonterminal v in this.variables)
            {
                if (variableNodeMap[v].isMarked)
                {
                    useful_backwards.Add(v);
                }
            }
            #endregion

            if (!useful_backwards.Contains(this.startSymbol))
            {
                throw new AutomataException(AutomataExceptionKind.LanguageOfGrammarIsEmpty);
            }

            ContextFreeGrammar g1 = this.RestrictToVariables(useful_backwards);

            HashSet <Nonterminal> useful_forwards = new HashSet <Nonterminal>();

            //Lemma 4.2, p. 89, Hopcroft-Ullman
            #region forward reachability
            Stack <Nonterminal> stack = new Stack <Nonterminal>();
            stack.Push(g1.StartSymbol);
            useful_forwards.Add(g1.StartSymbol);

            while (stack.Count > 0)
            {
                Nonterminal v = stack.Pop();
                foreach (Production p in g1.GetProductions(v))
                {
                    foreach (Nonterminal u in p.GetVariables())
                    {
                        if (!useful_forwards.Contains(u))
                        {
                            useful_forwards.Add(u);
                            stack.Push(u);
                        }
                    }
                }
            }

            #endregion

            ContextFreeGrammar g2 = g1.RestrictToVariables(useful_forwards);

            return(g2);
        }