示例#1
0
        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);
        }