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(); } } else { max = min; } pc.Expecting('}'); pc.Advance(); expr = new RegexRepeatExpression(expr, min, max); expr.SetLocation(line, column, position); break; } return(expr); }
static RegexExpression _FromFA <TAccept>(CharFA <TAccept> fa, HashSet <CharFA <TAccept> > visited) { if (!visited.Add(fa)) { return(null); } var trgs = fa.FillInputTransitionRangesGroupedByState(); bool isAccepting = fa.IsAccepting; RegexExpression expr = null; foreach (var trg in trgs) { if (1 == trg.Value.Count && 1 == trg.Value[0].Length) { RegexExpression le = new RegexLiteralExpression(trg.Value[0][0]); var next = _FromFA(trg.Key, visited); if (null != next) { le = new RegexConcatExpression(le, next); } if (null == expr) { expr = le; } else { expr = new RegexOrExpression(expr, le); } } else { var csel = new List <RegexCharsetEntry>(); foreach (var rng in trg.Value) { if (rng.First == rng.Last) { csel.Add(new RegexCharsetCharEntry(rng.First)); } else { csel.Add(new RegexCharsetRangeEntry(rng.First, rng.Last)); } } RegexExpression cse = new RegexCharsetExpression(csel); var next = _FromFA(trg.Key, visited); if (null != next) { cse = new RegexConcatExpression(cse, next); } if (null == expr) { expr = cse; } else { expr = new RegexOrExpression(expr, cse); } } } var isLoop = false; foreach (var val in fa.Descendants) { if (val == fa) { isLoop = true; break; } } if (isAccepting && !fa.IsFinal && !isLoop) { expr = new RegexOptionalExpression(expr); } return(expr); }