static IList <_LexRule> _ParseRules(TextReader inp) { var result = new List <_LexRule>(); var pc = LexContext.CreateFrom(inp); pc.EnsureStarted(); while (-1 != pc.Current) { pc.TrySkipCCommentsAndWhiteSpace(); if (-1 == pc.Current) { break; } pc.ClearCapture(); var l = pc.Line; var c = pc.Column; var p = pc.Position; var rule = new _LexRule(); rule.Line = l; rule.Column = c; rule.Position = p; if (!pc.TryReadCIdentifier()) { throw new ExpectingException(string.Format("Identifier expected at line {0}, column {1}, position {2}", l, c, p), l, c, p, "identifier"); } rule.Symbol = pc.GetCapture(); rule.Id = int.MinValue; pc.ClearCapture(); pc.TrySkipCCommentsAndWhiteSpace(); pc.Expecting('<', '=', '{'); if ('<' == pc.Current) { pc.Advance(); pc.Expecting(); var attrs = new List <KeyValuePair <string, object> >(); while (-1 != pc.Current && '>' != pc.Current) { pc.TrySkipCCommentsAndWhiteSpace(); pc.ClearCapture(); l = pc.Line; c = pc.Column; p = pc.Position; if (!pc.TryReadCIdentifier()) { throw new ExpectingException(string.Format("Identifier expected at line {0}, column {1}, position {2}", l, c, p), l, c, p, "identifier"); } var aname = pc.GetCapture(); pc.TrySkipCCommentsAndWhiteSpace(); pc.Expecting('=', '>', ','); if ('=' == pc.Current) { pc.Advance(); pc.TrySkipCCommentsAndWhiteSpace(); l = pc.Line; c = pc.Column; p = pc.Position; var value = pc.ParseJsonValue(); attrs.Add(new KeyValuePair <string, object>(aname, value)); if (0 == string.Compare("id", aname) && (value is double)) { rule.Id = (int)((double)value); if (0 > rule.Id) { throw new ExpectingException(string.Format("Expecting a non-negative integer at line {0}, column {1}, position {2}", l, c, p), l, c, p, "nonNegativeInteger"); } } } else { // boolean true attrs.Add(new KeyValuePair <string, object>(aname, true)); } pc.TrySkipCCommentsAndWhiteSpace(); pc.Expecting(',', '>'); if (',' == pc.Current) { pc.Advance(); } } pc.Expecting('>'); pc.Advance(); rule.Attributes = attrs.ToArray(); pc.TrySkipCCommentsAndWhiteSpace(); } pc.Expecting('=', '{'); var isAsm = '{' == pc.Current; pc.Advance(); if (!isAsm) { pc.TrySkipCCommentsAndWhiteSpace(); pc.Expecting('\'', '\"'); if ('\'' == pc.Current) { pc.Advance(); pc.ClearCapture(); pc.TryReadUntil('\'', '\\', false); pc.Expecting('\''); var pc2 = LexContext.Create(pc.GetCapture()); pc2.EnsureStarted(); pc2.SetLocation(pc.Line, pc.Column, pc.Position, pc.FileOrUrl); rule.Part = Lex.CompileRegexPart(pc2); pc.Advance(); } else { var str = pc.ParseJsonString(); rule.Part = Lex.CompileLiteralPart(str); } } else { rule.Part = Lex.Assemble(pc); pc.Expecting('}'); pc.Advance(); } result.Add(rule); } if (0 == result.Count) { throw new ExpectingException("Expecting lexer rules, but the document was empty", 0, 0, 0, "rule"); } return(result); }