public void Load(GrammarDocumentGroup documentGroup) { if (documentGroup.Items == null) { throw new ArgumentException("Grammar documents not loaded", "documentGroup"); } CheckGrammar(documentGroup); BuildSymbols(documentGroup); }
static int Main(string[] args) { if (args.Length == 0) { Console.WriteLine("Please provide the grammar folder argument"); return((int)ReturnValue.InvalidArgument); } string grammarFolder = args[0]; GrammarDocumentGroup.SchemaPath = "Schema.xsd"; var documentGroup = new GrammarDocumentGroup(); bool success = documentGroup.LoadWithValidation(grammarFolder, (sender, e) => { string severity; switch (e.Severity) { case XmlSeverityType.Error: severity = "Error"; break; case XmlSeverityType.Warning: severity = "Warning"; break; default: severity = "UnknownSeverityType"; break; } Console.WriteLine(severity + ": " + e.Message + $" ({e.Exception.Source})"); }); if (!success) { Console.WriteLine("Schema validation doesn't pass"); return((int)ReturnValue.InvalidGrammar); } var grammar = new Grammar(); try { grammar.Load(documentGroup); } catch (AggregateException pack) { foreach (Exception e in pack.InnerExceptions) { Console.WriteLine("Error: " + e.Message); } return((int)ReturnValue.InvalidGrammar); } Console.WriteLine(grammar.ToText()); return(0); }
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); } } }
private void CheckGrammar(GrammarDocumentGroup documentGroup) { var exceptions = new List <Exception>(); foreach (GrammarDocument document in documentGroup.Items) { foreach (XmlElement element in document.Content.GetElementsByTagName("Production")) { if (element.HasAttribute("output_order")) { string[] tokens = element.Attributes["output_order"].Value.Split(' '); if (tokens.Length != element.ChildNodes.Count) { throw new IllegalOutputOrderException(document.Path); } var found = new bool[tokens.Length]; for (int i = 0; i < tokens.Length; i++) { if (int.TryParse(tokens[i], out int number) && number < tokens.Length && !found[number]) { found[number] = true; } else { throw new IllegalOutputOrderException(document.Path); } } } } } bool hasTopSymbol = false; var symbolRefs = new Dictionary <string, SymbolId>(); var idGenerator = new SymbolId.Generator(); void checkSymbolsByTagName(string tagName) { foreach (GrammarDocument document in documentGroup.Items) { foreach (XmlElement element in document.Content.GetElementsByTagName(tagName)) { if (element.HasAttribute("name")) { string name = element.Attributes["name"].Value; if (symbolRefs.ContainsKey(name)) { exceptions.Add(new SymbolRedefinitionException(document.Path, name)); } else { symbolRefs.Add(name, idGenerator.Next()); } } if (element.HasAttribute("top") && XmlConvert.ToBoolean(element.Attributes["top"].Value)) { hasTopSymbol = true; } } } } checkSymbolsByTagName("Terminal"); checkSymbolsByTagName("Symbol"); foreach (GrammarDocument document in documentGroup.Items) { foreach (XmlElement element in document.Content.GetElementsByTagName("SymbolRef")) { Debug.Assert(element.HasAttribute("name")); string name = element.Attributes["name"].Value; if (!symbolRefs.ContainsKey(name)) { exceptions.Add(new SymbolRefNotFoundException(document.Path, name)); } } } if (!hasTopSymbol) { exceptions.Add(new Exception("Grammar has no top level symbol")); } if (exceptions.Count > 0) { throw new AggregateException(exceptions); } _symbolRefs = symbolRefs; _idGenerator = idGenerator; }