/// <summary> /// Actually performs the conversion and returns a new CNF grammar based on the old grammar /// </summary> internal CNFGrammar Convert() { if (_used) { throw new Exception("You can only use this object once"); } _used = true; var productions = GrammarHelpers.CloneGrammar(_grammar); StepStart(productions); StepTerm(productions); StepBin(productions); StepDel(productions); StepUnit(productions); var resultProductions = new List <Production>(); //var nonterminalProductions = new List<Production>(); //var terminalProductions = new List<Production>(); var producesEmptyWeight = 0.0; foreach (var production in productions) { if (production.Rhs.Count > 2) { throw new Exception("Didn't expect more than 2"); } else if (production.Rhs.Count == 2) { resultProductions.Add(production); } else if (production.Rhs.Count == 1) { var rhs = production.Rhs[0]; if (rhs.IsNonterminal) { throw new Exception("Didn't expect unit production"); } resultProductions.Add(production); } else if (production.Rhs.Count == 0) { producesEmptyWeight += production.Weight; // GetGrammarFromProductionList(production, productions); } } resultProductions.Add(new Production(_startSymbol, new Sentence(), producesEmptyWeight)); return(new CNFGrammar(resultProductions, _startSymbol)); }