static RegexExpression _ParseModifier(RegexExpression expr, ParseContext pc) { var line = pc.Line; var column = pc.Column; var position = pc.Position; switch (pc.Current) { case '*': expr = new RegexRepeatExpression(expr); expr.SetLocation(line, column, position); pc.Advance(); break; case '+': expr = new RegexRepeatExpression(expr, 1); expr.SetLocation(line, column, position); pc.Advance(); break; case '?': expr = new RegexOptionalExpression(expr); expr.SetLocation(line, column, position); pc.Advance(); break; case '{': pc.Advance(); pc.TrySkipWhiteSpace(); pc.Expecting('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ',', '}'); var min = -1; var max = -1; if (',' != pc.Current && '}' != pc.Current) { var l = pc.CaptureBuffer.Length; pc.TryReadDigits(); min = int.Parse(pc.GetCapture(l)); pc.TrySkipWhiteSpace(); } if (',' == pc.Current) { pc.Advance(); pc.TrySkipWhiteSpace(); pc.Expecting('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '}'); if ('}' != pc.Current) { var l = pc.CaptureBuffer.Length; pc.TryReadDigits(); max = int.Parse(pc.GetCapture(l)); pc.TrySkipWhiteSpace(); } } pc.Expecting('}'); pc.Advance(); expr = new RegexRepeatExpression(expr, min, max); expr.SetLocation(line, column, position); break; } return(expr); }
static string _ParseAttrName(ParseContext pc) { var l = pc.CaptureBuffer.Length; pc.TryReadUntil(false, '(', ')', '[', ']', '{', '}', '<', '>', ',', ':', ';', '=', '|', '/', '\'', '\"', ' ', '\t', '\r', '\n', '\f', '\v'); return(pc.GetCapture(l)); }
/// <summary> /// Pattern matches through a string of text /// </summary> /// <param name="context">The parse context to search</param> /// <returns>A <see cref="CharFAMatch"/> that contains the match information, or null if the match is not found.</returns> public CharFAMatch Match(ParseContext context) { context.EnsureStarted(); var line = context.Line; var column = context.Column; var position = context.Position; var l = context.CaptureBuffer.Length; var success = false; // keep going until we find something or reach the end while (-1 != context.Current && !(success = _DoMatch(context))) { line = context.Line; column = context.Column; position = context.Position; l = context.CaptureBuffer.Length; } if (success) { return(new CharFAMatch( line, column, position, context.GetCapture(l))); } return(null); }
static string _ParseIdentifier(ParseContext pc) { pc.TrySkipCCommentsAndWhiteSpace(); if (-1 == pc.Current) { pc.Expecting(); return(null); } var l = pc.CaptureBuffer.Length; if ('_' != pc.Current && !char.IsLetter((char)pc.Current)) { pc.Expecting("ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz".ToCharArray().Convert <int>().ToArray()); } pc.CaptureCurrent(); while (-1 != pc.Advance() && ('_' == pc.Current || '-' == pc.Current || char.IsLetterOrDigit((char)pc.Current))) { pc.CaptureCurrent(); } pc.TrySkipCCommentsAndWhiteSpace(); return(pc.GetCapture(l)); }
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 <RegexCharsetEntry> _ParseRanges(ParseContext pc) { pc.EnsureStarted(); var result = new List <RegexCharsetEntry>(); RegexCharsetEntry next = null; bool readDash = false; while (-1 != pc.Current && ']' != pc.Current) { switch (pc.Current) { case '[': // char class if (null != next) { result.Add(next); if (readDash) { result.Add(new RegexCharsetCharEntry('-')); } result.Add(new RegexCharsetCharEntry('-')); } pc.Advance(); pc.Expecting(':'); pc.Advance(); var l = pc.CaptureBuffer.Length; pc.TryReadUntil(':', false); var n = pc.GetCapture(l); pc.Advance(); pc.Expecting(']'); pc.Advance(); result.Add(new RegexCharsetClassEntry(n)); readDash = false; next = null; break; case '\\': //pc.Advance(); //pc.Expecting(); var ch = (char)_ParseEscape(pc); if (null == next) { next = new RegexCharsetCharEntry(ch); } else { if (readDash) { result.Add(new RegexCharsetRangeEntry(((RegexCharsetCharEntry)next).Value, ch)); next = null; readDash = false; } else { result.Add(next); next = new RegexCharsetCharEntry(ch); } } break; case '-': pc.Advance(); if (null == next) { next = new RegexCharsetCharEntry('-'); readDash = false; } else { if (readDash) { result.Add(next); } readDash = true; } break; default: if (null == next) { next = new RegexCharsetCharEntry((char)pc.Current); } else { if (readDash) { result.Add(new RegexCharsetRangeEntry(((RegexCharsetCharEntry)next).Value, (char)pc.Current)); next = null; readDash = false; } else { result.Add(next); next = new RegexCharsetCharEntry((char)pc.Current); } } pc.Advance(); break; } } if (null != next) { result.Add(next); if (readDash) { next = new RegexCharsetCharEntry('-'); result.Add(next); } } return(result); }
internal static LexDocument Parse(ParseContext pc) { var result = new LexDocument(); while (-1 != pc.Current) { var line = pc.Line; var column = pc.Column; var position = pc.Position; LexNode.SkipCommentsAndWhitespace(pc); while ('\n' == pc.Current) { pc.Advance(); LexNode.SkipCommentsAndWhitespace(pc); } var id = LexNode.ParseIdentifier(pc); if (string.IsNullOrEmpty(id)) { pc.Advance(); LexNode.SkipCommentsAndWhitespace(pc); continue; } LexNode.SkipCommentsAndWhitespace(pc); pc.Expecting(':', '-', '='); if (':' == pc.Current) // attribute set { pc.Advance(); var d = new LexAttributeList(); while (-1 != pc.Current && '\n' != pc.Current) { var attr = LexAttribute.Parse(pc); d.Add(attr); LexNode.SkipCommentsAndWhitespace(pc); pc.Expecting('\n', ',', -1); if (',' == pc.Current) { pc.Advance(); } } result.AttributeSets.Add(id, d); LexNode.SkipCommentsAndWhitespace(pc); } else if ('=' == pc.Current) { pc.Advance(); LexNode.SkipCommentsAndWhitespace(pc); pc.Expecting('\''); pc.Advance(); var l = pc.CaptureBuffer.Length; pc.TryReadUntil('\'', '\\', false); pc.Expecting('\''); pc.Advance(); var rx = pc.GetCapture(l); // make sure to capture the line numbers properly: var rpc = ParseContext.Create(rx); rpc.EnsureStarted(); rpc.SetLocation(pc.Line, pc.Column, pc.Position); var rule = new LexRule(id, RegexExpression.Parse(rpc)); rule.SetLocation(line, column, position); result.Rules.Add(rule); } else if ('-' == pc.Current) { pc.TrySkipUntil('\n', true); } LexNode.SkipCommentsAndWhitespace(pc); if ('\n' == pc.Current) { pc.Advance(); } } return(result); }