private void BuildSymbols(GrammarDocumentGroup documentGroup) { _symbols = new Dictionary <SymbolId, Symbol>(); SymbolId startId = _idGenerator.Next(); _start = new NonTerminalSymbol(startId, ReservedCharacter + "Start"); _symbols.Add(startId, _start); foreach (GrammarDocument document in documentGroup.Items) { foreach (XmlElement element in document.Content.DocumentElement.ChildNodes) { BuildSymbol(element); } } }
public Production(NonTerminalSymbol symbol, SymbolId id) { Symbol = symbol; _body = new SymbolId[] { id }; }
private SymbolId BuildSymbol(XmlElement element) { string name = element.Attributes["name"]?.Value; SymbolId id = name != null ? _symbolRefs[name] : _idGenerator.Next(); switch (element.Name) { case "Terminal": Debug.Assert(element.ChildNodes.Count == 2); Debug.Assert(element.FirstChild.Name == "in"); string input = element.FirstChild.InnerText; Debug.Assert(element.LastChild.Name == "out"); string output = element.LastChild.InnerText; _symbols.Add(id, new TerminalSymbol(id, input, output, name)); break; case "Symbol": var symbol = new NonTerminalSymbol(id, name); foreach (XmlElement subElement in element.ChildNodes) { switch (subElement.Name) { case "Terminal": case "Symbol": symbol.AddProduction(BuildSymbol(subElement)); break; case "SymbolRef": symbol.AddProduction(GetRefId(subElement)); break; case "Production": IReadOnlyList <SymbolId> body = BuildProduction(subElement, out int[] output_order); symbol.AddProduction(body, output_order); break; default: Debug.Fail("Unrecognized symbol type" + subElement.Name); break; } } _symbols.Add(id, symbol); break; default: Debug.Fail("Unrecognized symbol type" + element.Name); break; } if (element.HasAttribute("top") && XmlConvert.ToBoolean(element.Attributes["top"].Value)) { _start.AddProduction(id); } return(id); }
public Production(NonTerminalSymbol symbol, IReadOnlyList <SymbolId> body, IReadOnlyList <int> outputOrder) { Symbol = symbol; _body = body.ToArray(); _outputOrder = outputOrder?.ToArray(); }