static IList <EbnfMessage> _TryParseExpressions(ParseNode parent, int firstChildIndex, out EbnfExpression result) { var msgs = new List <EbnfMessage>(); result = null; var or = new List <IList <EbnfExpression> >(); var seq = new List <EbnfExpression>(); for (int ic = parent.Children.Count, i = firstChildIndex; i < ic; ++i) { EbnfExpression expr; var pn = parent.Children[i]; switch (pn.SymbolId) { case EbnfParser.expression: msgs.AddRange(_TryParseExpression(parent.Children[i], out expr)); seq.Add(expr); break; case EbnfParser.or: or.Add(seq); seq = new List <EbnfExpression>(); break; default: break; } } or.Add(seq); result = null; switch (or.Count) { case 0: result = null; break; case 1: result = _SeqToExpression(or[0]); break; default: var state = 0; var oe = new EbnfOrExpression(); for (int ic = or.Count, i = 0; i < ic; ++i) { switch (state) { case 0: oe.Left = _SeqToExpression(or[i]); state = 1; break; case 1: oe.Right = _SeqToExpression(or[i]); state = 2; break; case 2: oe = new EbnfOrExpression(oe, null); oe.Right = _SeqToExpression(or[i]); break; } } //if (0 == state || 2 == state) // result = oe.Left; //else result = oe; break; } return(msgs); }
static EbnfExpression _ParseExpression(EbnfDocument doc, ParseContext pc) { EbnfExpression current = null; EbnfExpression 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(); current = new EbnfOrExpression(current, _ParseExpression(doc, pc)); current.SetLocationInfo(line, column, position); break; case '(': pc.Advance(); e = _ParseExpression(doc, pc); current.SetLocationInfo(line, column, position); pc.Expecting(')'); pc.Advance(); e.SetLocationInfo(line, column, position); if (null == current) { current = e; } else { current = new EbnfConcatExpression(current, e); } break; case '[': pc.Advance(); e = new EbnfOptionalExpression(_ParseExpression(doc, pc)); e.SetLocationInfo(line, column, position); pc.TrySkipCCommentsAndWhiteSpace(); pc.Expecting(']'); pc.Advance(); if (null == current) { current = e; } else { current = new EbnfConcatExpression(current, e); } break; case '{': pc.Advance(); e = new EbnfRepeatExpression(_ParseExpression(doc, pc)); e.SetLocationInfo(line, column, position); pc.TrySkipCCommentsAndWhiteSpace(); pc.Expecting('}'); pc.Advance(); if ('+' == pc.Current) { pc.Advance(); ((EbnfRepeatExpression)e).IsOptional = false; } if (null == current) { current = e; } else { current = new EbnfConcatExpression(current, e); } break; case '\"': e = new EbnfLiteralExpression(pc.ParseJsonString()); if (null == current) { current = e; } else { current = new EbnfConcatExpression(current, e); } e.SetLocationInfo(line, column, position); break; case '\'': pc.Advance(); pc.ClearCapture(); pc.TryReadUntil('\'', '\\', false); pc.Expecting('\''); pc.Advance(); e = new EbnfRegexExpression(pc.Capture); if (null == current) { current = e; } else { current = new EbnfConcatExpression(current, e); } e.SetLocationInfo(line, column, position); break; case ';': case ']': case ')': case '}': return(current); default: e = new EbnfRefExpression(_ParseIdentifier(pc)); if (null == current) { current = e; } else { current = new EbnfConcatExpression(current, e); } e.SetLocationInfo(line, column, position); break; } } pc.TrySkipCCommentsAndWhiteSpace(); return(current); }
public override IList <IList <string> > ToDisjunctions(EbnfDocument parent, Cfg cfg) { string sid = null; var sr = Expression as EbnfRefExpression; if (null != parent && null != sr) { sid = string.Concat(sr.Symbol, "list"); } if (string.IsNullOrEmpty(sid)) { var cc = Expression as EbnfConcatExpression; if (null != cc) { sr = cc.Right as EbnfRefExpression; if (null != sr) { sid = string.Concat(sr.Symbol, "listtail"); } } } if (string.IsNullOrEmpty(sid)) { sid = "implicitlist"; } var _listId = cfg.GetUniqueId(sid); var attrs = new AttributeSet(); attrs.Add("collapsed", true); cfg.AttributeSets.Add(_listId, attrs); var expr = new EbnfOrExpression( new EbnfConcatExpression( new EbnfRefExpression(_listId), Expression), Expression); //if (IsOptional) // expr = new EbnfOrExpression(expr, null); foreach (var nt in expr.ToDisjunctions(parent, cfg)) { CfgRule r = new CfgRule(); r.Left = _listId; foreach (var s in nt) { if (1 < r.Right.Count && null == s) { continue; } r.Right.Add(s); } if (!cfg.Rules.Contains(r)) { cfg.Rules.Add(r); } } if (!IsOptional) { return(new List <IList <string> >(new IList <string>[] { new List <string>(new string[] { _listId }) })); } else { var result = new List <IList <string> >(); result.Add(new List <string>(new string[] { _listId })); result.Add(new List <string>()); return(result); } }