public void LoadGrammar(Stream stream) { var schemas = new XmlSchemaSet(); string pwd = AppDomain.CurrentDomain.BaseDirectory; schemas.Add("http://savva.moe/compiler/grammar.xsd", Path.Combine(pwd, "Schemas", "GrammarSchema.xsd")); var rules = XmlReader.Create(stream, new XmlReaderSettings { ValidationType = ValidationType.Schema, Schemas = schemas }); var g = new Grammar.Grammar(); while (rules.Read()) { if (!rules.IsStartElement()) continue; string term, product; switch (rules.Name) { case "grammar": continue; case "start": string start = rules.GetAttribute("rule"); if (string.IsNullOrWhiteSpace(start)) throw new XmlException("Start rule cannot be empty"); g.Start = new NonTerminal(start); continue; case "rule": term = rules.GetAttribute("name"); product = rules.GetAttribute("production"); break; default: throw new XmlException($"Rules definition cannot contain '{rules.Name}' element"); } if (string.IsNullOrWhiteSpace(term)) throw new ParserException("Rule's term cannot be empty"); if (string.IsNullOrWhiteSpace(product)) throw new NotImplementedException("Epsilon-rules aren't yet implemented"); var production = product .Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries) .Select<string, Symbol>(t => { if (t.StartsWith("$")) return new Terminal(t.Substring(1)); return new NonTerminal(t); }) .ToList(); g.Add(term, production); } Grammar = g; }
public void LoadGrammar(Stream stream) { var schemas = new XmlSchemaSet(); string pwd = AppDomain.CurrentDomain.BaseDirectory; schemas.Add("http://savva.moe/compiler/grammar.xsd", Path.Combine(pwd, "Schemas", "GrammarSchema.xsd")); var rules = XmlReader.Create(stream, new XmlReaderSettings { ValidationType = ValidationType.Schema, Schemas = schemas }); var g = new Grammar.Grammar(); while (rules.Read()) { if (!rules.IsStartElement()) { continue; } string term, product; switch (rules.Name) { case "grammar": continue; case "start": string start = rules.GetAttribute("rule"); if (string.IsNullOrWhiteSpace(start)) { throw new XmlException("Start rule cannot be empty"); } g.Start = new NonTerminal(start); continue; case "rule": term = rules.GetAttribute("name"); product = rules.GetAttribute("production"); break; default: throw new XmlException($"Rules definition cannot contain '{rules.Name}' element"); } if (string.IsNullOrWhiteSpace(term)) { throw new ParserException("Rule's term cannot be empty"); } if (string.IsNullOrWhiteSpace(product)) { throw new NotImplementedException("Epsilon-rules aren't yet implemented"); } var production = product .Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries) .Select <string, Symbol>(t => { if (t.StartsWith("$")) { return(new Terminal(t.Substring(1))); } return(new NonTerminal(t)); }) .ToList(); g.Add(term, production); } Grammar = g; }