bool _HasExpression(EbnfExpression search, EbnfExpression match) { if (Equals(search, match)) { return(true); } var b = search as EbnfBinaryExpression; if (null != b) { if (_HasExpression(b.Left, match) || _HasExpression(b.Right, match)) { return(true); } } var u = search as EbnfUnaryExpression; if (null != u) { if (_HasExpression(u.Expression, match)) { return(true); } } return(false); }
void _VisitFetchTerminals(EbnfExpression expr, HashSet <EbnfExpression> terms) { var l = expr as EbnfLiteralExpression; if (null != l) { terms.Add(l); return; } var r = expr as EbnfRegexExpression; if (null != r) { terms.Add(r); return; } var u = expr as EbnfUnaryExpression; if (null != u) { _VisitFetchTerminals(u.Expression, terms); return; } var b = expr as EbnfBinaryExpression; if (null != b) { _VisitFetchTerminals(b.Left, terms); _VisitFetchTerminals(b.Right, terms); return; } }
public string GetIdForExpression(EbnfExpression expression) { foreach (var prod in Productions) { if (Equals(prod.Value.Expression, expression)) { return(prod.Key); } } return(""); }
public string GetContainingIdForExpression(EbnfExpression expression) { foreach (var prod in Productions) { if (_HasExpression(prod.Value.Expression, expression)) { return(prod.Key); } } return(""); }
public EbnfOrExpression(EbnfExpression left, params EbnfExpression[] right) { if (null == right) { right = new EbnfExpression[] { null } } ; Left = left; for (var i = 0; i < right.Length; ++i) { if (Right == null) { Right = right[i]; } else { Right = new EbnfOrExpression(Right, right[i]); } } }
public EbnfOptionalExpression(EbnfExpression expression) { Expression = expression; }
public EbnfProduction(EbnfExpression expression) { Expression = expression; }
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); }
void _ValidateExpression(EbnfExpression expr, IDictionary <string, int> refCounts, IList <EbnfMessage> messages) { var l = expr as EbnfLiteralExpression; if (null != l) { var i = GetIdForExpression(l); // don't count itself. only things just like itself if (!string.IsNullOrEmpty(i) && !ReferenceEquals(Productions[i].Expression, l)) { refCounts[i] += 1; } } var rx = expr as EbnfRegexExpression; if (null != rx) { try { CharFA.Parse(rx.Value); } catch (ExpectingException) { messages.Add( new EbnfMessage( EbnfErrorLevel.Error, 12, "Invalid regular expression", expr.Line, expr.Column, expr.Position)); } var i = GetIdForExpression(rx); if (!string.IsNullOrEmpty(i) && !ReferenceEquals(Productions[i].Expression, l)) { refCounts[i] += 1; } } var r = expr as EbnfRefExpression; if (null != r) { int rc; if (null == r.Symbol) { messages.Add( new EbnfMessage( EbnfErrorLevel.Error, 4, "Null reference expression", expr.Line, expr.Column, expr.Position)); return; } if (!refCounts.TryGetValue(r.Symbol, out rc)) { messages.Add( new EbnfMessage( EbnfErrorLevel.Error, 1, string.Concat( "Reference to undefined symbol \"", r.Symbol, "\""), expr.Line, expr.Column, expr.Position)); return; } refCounts[r.Symbol] = rc + 1; return; } var b = expr as EbnfBinaryExpression; if (null != b) { if (null == b.Left && null == b.Right) { messages.Add( new EbnfMessage( EbnfErrorLevel.Warning, 3, "Nil expression", expr.Line, expr.Column, expr.Position)); return; } _ValidateExpression(b.Left, refCounts, messages); _ValidateExpression(b.Right, refCounts, messages); return; } var u = expr as EbnfUnaryExpression; if (null != u) { if (null == u.Expression) { messages.Add( new EbnfMessage( EbnfErrorLevel.Warning, 3, "Nil expression", expr.Line, expr.Column, expr.Position)); return; } _ValidateExpression(u.Expression, refCounts, messages); } }
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 IList <EbnfMessage> _TryParseExpression(ParseNode pn, out EbnfExpression result) { result = null; Debug.Assert(EbnfParser.expression == pn.SymbolId, "Not positioned on expression"); var msgs = new List <EbnfMessage>(); if (1 == pn.Children.Count) { var c = pn.Children[0]; if (EbnfParser.symbol == c.SymbolId) { ParseContext pc; var cc = c.Children[0]; //TODO: parse the regular expressions and literals to make sure they're valid. switch (cc.SymbolId) { case EbnfParser.identifier: result = new EbnfRefExpression(cc.Value); return(msgs); case EbnfParser.regex: pc = ParseContext.Create(cc.Value); pc.EnsureStarted(); pc.Advance(); pc.TryReadUntil('\'', '\\', false); result = new EbnfRegexExpression(pc.GetCapture()); return(msgs); case EbnfParser.literal: pc = ParseContext.Create(cc.Value); pc.EnsureStarted(); pc.Advance(); pc.TryReadUntil('\"', '\\', false); result = new EbnfLiteralExpression(pc.GetCapture()); return(msgs); case EbnfParser.lbrace: msgs.AddRange(_TryParseExpressions(c, 1, out result)); result = new EbnfRepeatExpression(result); if (EbnfParser.rbracePlus == c.Children[c.Children.Count - 1].SymbolId) { ((EbnfRepeatExpression)result).IsOptional = false; } return(msgs); case EbnfParser.lbracket: msgs.AddRange(_TryParseExpressions(c, 1, out result)); result = new EbnfOptionalExpression(result); return(msgs); case EbnfParser.lparen: msgs.AddRange(_TryParseExpressions(c, 1, out result)); return(msgs); default: break; } } } return(msgs); }
public EbnfRepeatExpression(EbnfExpression expression) { Expression = expression; }