/// <summary>
        /// Generates a CNF for a given grammar or returns null if the Grammar doesn't produce any words.
        /// </summary>
        /// <param name="g">the original grammar</param>
        /// <returns>the CNF or null</returns>
        public static ContextFreeGrammar getEquivalentCNF(ContextFreeGrammar g)
        {
            if (g == null)
            {
                return(null);
            }
            if (g.IsInCNF())
            {
                return(g);
            }

            try
            {
                ContextFreeGrammar res = ContextFreeGrammar.MkCNF(g);

                //handle empty string
                res.setAcceptanceForEmptyString(g.acceptsEmptyString());

                return(res);
            }
            catch (AutomataException e)
            {
                if (g.acceptsEmptyString())
                {
                    var res = new ContextFreeGrammar(new Nonterminal("S"), new Production[] { new Production(new Nonterminal("S"), new GrammarSymbol[] { new Nonterminal("S"), new Nonterminal("S") }) });
                    res.setAcceptanceForEmptyString(true);
                    return(res);
                }
                return(null);
            }
        }
        /// <summary>
        /// Generates a CFG that accepts the prefix closure of a given grammar.
        /// </summary>
        /// <param name="g">the original grammar</param>
        /// <returns>the prefix closure</returns>
        public static ContextFreeGrammar getPrefixClosure(ContextFreeGrammar g)
        {
            Func <Nonterminal, Nonterminal> prefixFor = delegate(Nonterminal x)
            {
                return(new Nonterminal(x.Name + "PREFIX"));
            };

            if (g == null)
            {
                return(g);
            }
            if (!g.IsInCNF())
            {
                g = getEquivalentCNF(g);
            }
            if (g == null)
            {
                return(g);
            }
            Nonterminal prefixStart       = prefixFor(g.StartSymbol);
            var         prefixProductions = new List <Production>();

            foreach (Production p in g.GetProductions())
            {
                //add original
                prefixProductions.Add(p);

                Nonterminal prefixNT = prefixFor(p.Lhs);
                if (p.Rhs.Length == 2) // case:  X->AB      ==>     X' ->A' | AB'
                {
                    prefixProductions.Add(new Production(prefixNT, new GrammarSymbol[] { p.Rhs[0], prefixFor((Nonterminal)p.Rhs[1]) }));
                    prefixProductions.Add(new Production(prefixNT, new GrammarSymbol[] { prefixFor((Nonterminal)p.Rhs[0]) }));
                }
                else // case:  X->a   ==>    X'->a
                {
                    prefixProductions.Add(new Production(prefixNT, new GrammarSymbol[] { p.Rhs[0] }));
                }
            }

            var res = new ContextFreeGrammar(prefixStart, prefixProductions);

            res.setAcceptanceForEmptyString(true);

            return(res);
        }