Beispiel #1
0
 public CFGSubtypingAPIGenerator(CFG grammar, string grammarName, bool generateFluentAPI)
 {
     if (!grammar.InGreibachNormalForm())
     {
         throw new Exception("can generate API only for grammars in Greibach normal form");
     }
     this.grammar           = grammar;
     this.grammarName       = grammarName;
     this.generateFluentAPI = generateFluentAPI;
 }
Beispiel #2
0
 /// <summary>
 /// Transforms grammar into Greibach normal form, i.e.,
 /// where productions are of the form `v ::= t s1 s2...`, `v` a variable,
 /// `t` a terminal.
 /// The grammar's start variable may be nullable, `v0 ::= epsilon`.
 /// </summary>
 /// <param name="grammar">target grammar</param>
 /// <returns>grammar in Greibach normal form</returns>
 public static CFG ToGreibachNormalForm(this CFG grammar)
 {
     if (grammar.InGreibachNormalForm())
     {
         return(grammar);
     }
     while (true)
     {
         grammar = grammar.RemoveEpsilonProductions().RemoveLeftRecursion();
         OrderedHashSet <Production> productions = new OrderedHashSet <Production>();
         foreach (Production production in grammar.productions)
         {
             if (production.IsEpsilonProduction() || grammar.Terminals().Contains(production.rhs[0]))
             {
                 productions.Add(production);
             }
             else
             {
                 string rhsStartVariable = production.rhs[0];
                 foreach (Production otherProduction in grammar.productions)
                 {
                     if (otherProduction.lhs == rhsStartVariable)
                     {
                         List <string> newRHS = new List <string>();
                         newRHS.AddRange(otherProduction.rhs);
                         newRHS.AddRange(production.rhs.Skip(1));
                         productions.Add(new Production(production.lhs, newRHS.ToArray()));
                     }
                 }
             }
         }
         grammar = verifyConsistency(grammar, new CFG(grammar.startVariable, productions));
         if (grammar.InGreibachNormalForm())
         {
             return(grammar);
         }
     }
 }