private Nonterminal Map(NonterminalExpr rule) { if (!Nonterminals.TryGetValue(rule, out var mapped)) { mapped = new Nonterminal(rule.Name); Nonterminals.Add(rule, mapped); foreach (var chain in rule.Body) { var body = new List <Symbol>(); foreach (var symbol in chain) { switch (symbol) { case TerminalExpr terminal: body.Add(Map(terminal)); break; case NonterminalExpr nonterminal: body.Add(Map(nonterminal)); break; } } Productions.Add(new Production(mapped, body)); } } return(mapped); }
public Grammar From(NonterminalExpr startSymbol) { return(new Grammar(Map(startSymbol), Productions)); }