/// <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));
}