Example #1
0
        /// <summary>
        /// Simplify context-free grammar by removing unreachable symbols and productions and productions of
        /// the form V ::= V.
        /// </summary>
        /// <param name="grammar">target grammar</param>
        /// <returns>simplified grammar</returns>
        public static CFG Simplify(this CFG grammar)
        {
            OrderedHashSet <Production> productions = new OrderedHashSet <Production>();
            OrderedHashSet <string>     newSymbols = new OrderedHashSet <string>(), seenSymbols = new OrderedHashSet <string>();

            newSymbols.Add(grammar.startVariable);
            while (newSymbols.Count() > 0)
            {
                foreach (string symbol in newSymbols)
                {
                    seenSymbols.Add(symbol);
                }
                OrderedHashSet <string> nextSymbols = new OrderedHashSet <string>();
                foreach (Production production in grammar.productions)
                {
                    if (newSymbols.Contains(production.lhs) && (production.rhs.Length != 1 || production.rhs[0] != production.lhs))
                    {
                        productions.Add(production);
                        foreach (string symbol in production.rhs)
                        {
                            if (!seenSymbols.Contains(symbol))
                            {
                                nextSymbols.Add(symbol);
                            }
                        }
                    }
                }
                newSymbols = nextSymbols;
            }
            return(verifyConsistency(grammar, new CFG(grammar.startVariable, productions)));
        }
Example #2
0
 /// <summary>
 /// Checks whether the grammar has a left-recursive production, i.e.,
 /// of the form `v ::= v s1 s2...` (can also be indirect).
 /// </summary>
 /// <param name="grammar">context-free grammar</param>
 /// <returns>whether grammar has left-recursion</returns>
 public static bool HasLeftRecursion(this CFG grammar)
 {
     foreach (string variable in grammar.Variables())
     {
         OrderedHashSet <string> reachableVariables = new OrderedHashSet <string>();
         reachableVariables.Add(variable);
         int n = 0;
         while (reachableVariables.Count() > n)
         {
             n = reachableVariables.Count();
             OrderedHashSet <string> newReachableVariables = new OrderedHashSet <string>();
             foreach (string reachableVariable in reachableVariables)
             {
                 foreach (Production production in grammar.productions)
                 {
                     if (production.lhs == reachableVariable && production.rhs.Length > 0)
                     {
                         string first = production.rhs[0];
                         if (first == variable)
                         {
                             return(true);
                         }
                         else if (grammar.Variables().Contains(first))
                         {
                             newReachableVariables.Add(first);
                         }
                     }
                 }
             }
             foreach (string newVariable in newReachableVariables)
             {
                 reachableVariables.Add(newVariable);
             }
         }
     }
     return(false);
 }