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(); } } }
public override string ToString() { if (null == Document) { return(""); } if (string.IsNullOrEmpty(Document.FileOrUrl)) { return("@import <<in-memory>>;"); } return("@import \"" + XbnfNode.Escape(Document.FileOrUrl) + "\";"); }
public string ToString(string fmt) { var sb = new StringBuilder(); for (int ic = Includes.Count, i = 0; i < ic; ++i) { sb.Append("@include "); sb.Append("\"" + XbnfNode.Escape(Includes[i].Document.FileOrUrl) + "\""); sb.AppendLine(";"); } var oc = Options.Count; if (0 < oc) { sb.Append("@options "); for (var i = 0; i < oc; ++i) { if (0 != i) { sb.Append(", "); } sb.Append(Options[i]); } sb.AppendLine(";"); } if ("gnc" == fmt) { for (int ic = Productions.Count, i = 0; i < ic; ++i) { sb.AppendLine(Productions[i].ToString("pnc")); } } else if ("xc" == fmt) { for (int ic = Productions.Count, i = 0; i < ic; ++i) { sb.AppendLine(Productions[i].ToString("xc")); } } else { for (int ic = Productions.Count, i = 0; i < ic; ++i) { sb.AppendLine(Productions[i].ToString()); } } return(sb.ToString()); }
static string _ToRegex(XbnfDocument d, XbnfExpression e, bool first, bool gplex = false) { var le = e as XbnfLiteralExpression; if (null != le) { var s = _EscapeLiteral(XbnfNode.Escape(le.Value), !gplex); if (gplex) { s = string.Concat("\"", s, "\""); } return(s); } var rxe = e as XbnfRegexExpression; if (null != rxe) { var r = rxe.Value; if (gplex) { r = r.Replace("\"", "\\\""); } return(first ? r : string.Concat("(", r, ")")); } var rfe = e as XbnfRefExpression; if (null != rfe) { _ToRegex(d, d.Productions[rfe.Symbol].Expression, first, gplex); } var re = e as XbnfRepeatExpression; if (null != re) { if (re.IsOptional) { return(string.Concat("(", _ToRegex(d, re.Expression, true, gplex), ")*")); } else { return(string.Concat("(", _ToRegex(d, re.Expression, true, gplex), ")+")); } } var oe = e as XbnfOrExpression; if (null != oe) { if (!first) { return(string.Concat("(", _ToRegex(d, oe.Left, false, gplex), "|", _ToRegex(d, oe.Right, false, gplex), ")")); } else { return(string.Concat(_ToRegex(d, oe.Left, false, gplex), "|", _ToRegex(d, oe.Right, false, gplex))); } } var oc = e as XbnfConcatExpression; if (null != oc) { return(string.Concat(_ToRegex(d, oc.Left, false, gplex), _ToRegex(d, oc.Right, false, gplex))); } var ope = e as XbnfOptionalExpression; if (null != ope) { return(string.Concat("(", _ToRegex(d, ope.Expression, true, gplex), ")?")); } return(""); }
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); }