static void _ParseIncludes(LexContext pc, IList <string> result) { pc.TrySkipCCommentsAndWhiteSpace(); while ('@' == pc.Current) { pc.Advance(); var s = XbnfNode.ParseIdentifier(pc); if ("include" == s) { pc.TrySkipCCommentsAndWhiteSpace(); var lit = XbnfExpression.Parse(pc) as XbnfLiteralExpression; if (!result.Contains(lit.Value)) { result.Add(lit.Value); } pc.TryReadCCommentsAndWhitespace(); pc.Advance(); pc.TryReadCCommentsAndWhitespace(); } else { while (-1 != pc.Current && ';' != pc.Current) { pc.Advance(); } if (';' == pc.Current) { pc.Advance(); } pc.TrySkipCCommentsAndWhiteSpace(); } } }
internal static XbnfDocument Parse(LexContext pc) { var result = new XbnfDocument(); if (!string.IsNullOrEmpty(pc.FileOrUrl)) { result.SetFilename(pc.FileOrUrl); } while (-1 != pc.Current && '}' != pc.Current) { pc.TrySkipCCommentsAndWhiteSpace(); while ('@' == pc.Current) // directives { pc.Advance(); var l = pc.Line; var c = pc.Column; var p = pc.Position; var str = XbnfNode.ParseIdentifier(pc); if (0 == string.Compare("include", str, StringComparison.InvariantCulture)) { result.Includes.Add(_ParseIncludePart(result, pc)); } else if (0 == string.Compare("options", str, StringComparison.InvariantCulture)) { if (0 < result.Options.Count) { throw new ExpectingException("Duplicate directive \"options\" specified", l, c, p, pc.FileOrUrl); } while (-1 != pc.Current && ';' != pc.Current) { l = pc.Line; c = pc.Column; p = pc.Position; var opt = XbnfOption.Parse(pc); opt.SetLocation(l, c, p); result.Options.Add(opt); pc.TrySkipCCommentsAndWhiteSpace(); pc.Expecting(';', ','); if (',' == pc.Current) { pc.Advance(); } } pc.Expecting(';'); pc.Advance(); if (0 == result.Options.Count) { throw new ExpectingException("Expection options but \"options\" directive was empty", l, c, p, pc.FileOrUrl); } } else { throw new ExpectingException("Expecting \"include\" or \"options\"", l, c, p, pc.FileOrUrl, "include", "options"); } pc.TrySkipCCommentsAndWhiteSpace(); } if (pc.Current == '{') { pc.Advance(); var l = pc.Line; var c = pc.Column; var p = pc.Position; var s = ReadCode(pc); pc.Expecting('}'); pc.Advance(); var code = new XbnfCode(s); code.SetLocation(l, c, p); result.Code.Add(code); } else if (-1 != pc.Current) { if ('@' == pc.Current) { throw new ExpectingException("Expecting productions. Includes and options must be specified before any productions", pc.Line, pc.Column, pc.Position, pc.FileOrUrl, "Production"); } result.Productions.Add(XbnfProduction.Parse(pc)); } else // end of input { return(result); } // have to do this so trailing whitespace // doesn't get read as a production pc.TryReadCCommentsAndWhitespace(); } return(result); }