internal static XbnfExpression Parse(ParseContext pc) { XbnfExpression current = null; XbnfExpression e; long position; int line; int column; pc.TrySkipCCommentsAndWhiteSpace(); position = pc.Position; line = pc.Line; column = pc.Column; while (-1 != pc.Current && ']' != pc.Current && ')' != pc.Current && '}' != pc.Current && ';' != pc.Current) { pc.TrySkipCCommentsAndWhiteSpace(); position = pc.Position; line = pc.Line; column = pc.Column; switch (pc.Current) { case '|': pc.Advance(); position = pc.Position; line = pc.Line; column = pc.Column; current = new XbnfOrExpression(current, Parse(pc)); current.SetLocation(line, column, position); break; case '(': pc.Advance(); position = pc.Position; line = pc.Line; column = pc.Column; e = Parse(pc); current.SetLocation(line, column, position); pc.Expecting(')'); pc.Advance(); e.SetLocation(line, column, position); if (null == current) { current = e; } else { current = new XbnfConcatExpression(current, e); } break; case '[': pc.Advance(); e = new XbnfOptionalExpression(Parse(pc)); e.SetLocation(line, column, position); pc.TrySkipCCommentsAndWhiteSpace(); pc.Expecting(']'); pc.Advance(); if (null == current) { current = e; } else { current = new XbnfConcatExpression(current, e); } break; case '{': pc.Advance(); e = new XbnfRepeatExpression(Parse(pc)); e.SetLocation(line, column, position); pc.TrySkipCCommentsAndWhiteSpace(); pc.Expecting('}'); pc.Advance(); if ('+' == pc.Current) { pc.Advance(); ((XbnfRepeatExpression)e).IsOptional = false; } if (null == current) { current = e; } else { current = new XbnfConcatExpression(current, e); } break; case '\"': e = new XbnfLiteralExpression(pc.ParseJsonString()); if (null == current) { current = e; } else { current = new XbnfConcatExpression(current, e); } e.SetLocation(line, column, position); break; case '\'': pc.Advance(); pc.ClearCapture(); pc.TryReadUntil('\'', '\\', false); pc.Expecting('\''); pc.Advance(); e = new XbnfRegexExpression(pc.GetCapture()); if (null == current) { current = e; } else { current = new XbnfConcatExpression(current, e); } e.SetLocation(line, column, position); break; case ';': case ']': case ')': case '}': return(current); default: e = new XbnfRefExpression(ParseIdentifier(pc)); if (null == current) { current = e; } else { current = new XbnfConcatExpression(current, e); } e.SetLocation(line, column, position); break; } } pc.TrySkipCCommentsAndWhiteSpace(); return(current); }
static IList <IList <string> > _GetDysRepeat(XbnfDocument d, ICollection <string> syms, IDictionary <XbnfExpression, string> tmap, IDictionary <string, XbnfAttributeList> attrs, IList <KeyValuePair <string, IList <string> > > rules, XbnfProduction p, XbnfRepeatExpression re) { string sid = null; var sr = re.Expression as XbnfRefExpression; if (null != d && null != sr) { sid = string.Concat(sr.Symbol, "list"); } if (string.IsNullOrEmpty(sid)) { var cc = re.Expression as XbnfConcatExpression; if (null != cc) { sr = cc.Right as XbnfRefExpression; if (null != sr) { sid = string.Concat(sr.Symbol, "listtail"); } } } if (string.IsNullOrEmpty(sid)) { sid = "implicitlist"; } var listId = sid; var i = 2; var ss = listId; while (syms.Contains(ss)) { ss = string.Concat(listId, i.ToString()); ++i; } syms.Add(ss); var attr = new XbnfAttribute("collapsed", true); var attrlist = new XbnfAttributeList(); attrlist.Add(attr); attrs.Add(listId, attrlist); var expr = new XbnfOrExpression( new XbnfConcatExpression( new XbnfRefExpression(listId), re.Expression), re.Expression); foreach (var nt in _GetDysjunctions(d, syms, tmap, attrs, rules, p, expr)) { var l = new List <string>(); var r = new KeyValuePair <string, IList <string> >(listId, l); foreach (var s in nt) { if (1 < r.Value.Count && null == s) { continue; } r.Value.Add(s); } rules.Add(r); } if (!re.IsOptional) { return(new List <IList <string> >(new IList <string>[] { new List <string>(new string[] { listId }) })); } else { var res = new List <IList <string> >(); res.Add(new List <string>(new string[] { listId })); res.Add(new List <string>()); return(res); } }