private void StepTerm(ISet<Production> productions) {
var newProductions = new List<Production>();
var lookup = new Dictionary<Terminal, Nonterminal>();
foreach (var production in productions) {
if (production.Rhs.Count < 2) {
continue;
}
for (int i = 0; i < production.Rhs.Count; i++) {
var word = production.Rhs[i];
if (word.IsNonterminal) {
continue;
}
Terminal terminal = (Terminal)word;
Nonterminal fresh;
if (!lookup.TryGetValue(terminal, out fresh)) {
fresh = GetFresh();
lookup[terminal] = fresh;
newProductions.Add(
new Production(fresh, new Sentence { terminal })
);
}
production.Rhs[i] = fresh;
}
}
productions.UnionWith(newProductions);
}