示例#1
0
        public static FA Optional(FA expr, int accept = -1)
        {
            var result = expr.Clone();
            var f      = result.FirstAcceptingState;

            f.AcceptSymbol = accept;
            result.EpsilonTransitions.Add(f);
            return(result);
        }
示例#2
0
        public static FA Concat(IEnumerable <FA> exprs, int accept = -1)
        {
            FA result = null, left = null, right = null;

            foreach (var val in exprs)
            {
                if (null == val)
                {
                    continue;
                }
                //Debug.Assert(null != val.FirstAcceptingState);
                var nval = val.Clone();
                //Debug.Assert(null != nval.FirstAcceptingState);
                if (null == left)
                {
                    if (null == result)
                    {
                        result = nval;
                    }
                    left = nval;
                    //Debug.Assert(null != left.FirstAcceptingState);
                    continue;
                }
                if (null == right)
                {
                    right = nval;
                }

                //Debug.Assert(null != left.FirstAcceptingState);
                nval = right.Clone();
                _Concat(left, nval);
                right = null;
                left  = nval;

                //Debug.Assert(null != left.FirstAcceptingState);
            }
            if (null != right)
            {
                right.FirstAcceptingState.AcceptSymbol = accept;
            }
            else
            {
                result.FirstAcceptingState.AcceptSymbol = accept;
            }
            return(result);
        }
示例#3
0
        public static FA CaseInsensitive(FA expr, int accept = -1)
        {
            var result  = expr.Clone();
            var closure = new List <FA>();

            result.FillClosure(closure);
            for (int ic = closure.Count, i = 0; i < ic; ++i)
            {
                var fa = closure[i];
                var t  = new List <KeyValuePair <KeyValuePair <int, int>, FA> >(fa.InputTransitions);
                fa.InputTransitions.Clear();
                foreach (var trns in t)
                {
                    var f = char.ConvertFromUtf32(trns.Key.Key);
                    var l = char.ConvertFromUtf32(trns.Key.Value);
                    if (char.IsLower(f, 0))
                    {
                        if (!char.IsLower(l, 0))
                        {
                            throw new NotSupportedException("Attempt to make an invalid range case insensitive");
                        }
                        fa.InputTransitions.Add(trns.Key, trns.Value);
                        f = f.ToUpperInvariant();
                        l = l.ToUpperInvariant();
                        fa.InputTransitions.Add(new KeyValuePair <int, int>(char.ConvertToUtf32(f, 0), char.ConvertToUtf32(l, 0)), trns.Value);
                    }
                    else if (char.IsUpper(f, 0))
                    {
                        if (!char.IsUpper(l, 0))
                        {
                            throw new NotSupportedException("Attempt to make an invalid range case insensitive");
                        }
                        fa.InputTransitions.Add(trns.Key, trns.Value);
                        f = f.ToLowerInvariant();
                        l = l.ToLowerInvariant();
                        fa.InputTransitions.Add(new KeyValuePair <int, int>(char.ConvertToUtf32(f, 0), char.ConvertToUtf32(l, 0)), trns.Value);
                    }
                    else
                    {
                        fa.InputTransitions.Add(trns.Key, trns.Value);
                    }
                }
            }
            return(result);
        }
示例#4
0
        public static FA Repeat(FA expr, int minOccurs = -1, int maxOccurs = -1, int accept = -1)
        {
            expr = expr.Clone();
            if (minOccurs > 0 && maxOccurs > 0 && minOccurs > maxOccurs)
            {
                throw new ArgumentOutOfRangeException(nameof(maxOccurs));
            }
            FA result;

            switch (minOccurs)
            {
            case -1:
            case 0:
                switch (maxOccurs)
                {
                case -1:
                case 0:
                    //return Repeat(Optional(expr, accept),1,0,accept);
                    result = new FA();
                    var final = new FA(true, accept);
                    final.EpsilonTransitions.Add(result);
                    foreach (var afa in expr.FillAcceptingStates())
                    {
                        afa.IsAccepting = false;
                        afa.EpsilonTransitions.Add(final);
                    }
                    result.EpsilonTransitions.Add(expr);
                    result.EpsilonTransitions.Add(final);
                    //Debug.Assert(null != result.FirstAcceptingState);
                    return(result);

                case 1:
                    result = Optional(expr, accept);
                    //Debug.Assert(null != result.FirstAcceptingState);
                    return(result);

                default:
                    var l = new List <FA>();
                    expr = Optional(expr);
                    l.Add(expr);
                    for (int i = 1; i < maxOccurs; ++i)
                    {
                        l.Add(expr.Clone());
                    }
                    result = Concat(l, accept);
                    //Debug.Assert(null != result.FirstAcceptingState);
                    return(result);
                }

            case 1:
                switch (maxOccurs)
                {
                case -1:
                case 0:
                    result = new FA();
                    var final = new FA(true, accept);
                    final.EpsilonTransitions.Add(result);
                    foreach (var afa in expr.FillAcceptingStates())
                    {
                        afa.IsAccepting = false;
                        afa.EpsilonTransitions.Add(final);
                    }
                    result.EpsilonTransitions.Add(expr);
                    //Debug.Assert(null != result.FirstAcceptingState);
                    return(result);

                case 1:
                    //Debug.Assert(null != expr.FirstAcceptingState);
                    return(expr);

                default:
                    result = Concat(new FA[] { expr, Repeat(expr.Clone(), 0, maxOccurs - 1) }, accept);
                    //Debug.Assert(null != result.FirstAcceptingState);
                    return(result);
                }

            default:
                switch (maxOccurs)
                {
                case -1:
                case 0:
                    result = Concat(new FA[] { Repeat(expr, minOccurs, minOccurs, accept), Repeat(expr, 0, 0, accept) }, accept);
                    //Debug.Assert(null != result.FirstAcceptingState);
                    return(result);

                case 1:
                    throw new ArgumentOutOfRangeException(nameof(maxOccurs));

                default:
                    if (minOccurs == maxOccurs)
                    {
                        var l = new List <FA>();
                        l.Add(expr);
                        //Debug.Assert(null != expr.FirstAcceptingState);
                        for (int i = 1; i < minOccurs; ++i)
                        {
                            var e = expr.Clone();
                            //Debug.Assert(null != e.FirstAcceptingState);
                            l.Add(e);
                        }
                        result = Concat(l, accept);
                        //Debug.Assert(null != result.FirstAcceptingState);
                        return(result);
                    }
                    result = Concat(new FA[] { Repeat(expr.Clone(), minOccurs, minOccurs, accept), Repeat(Optional(expr.Clone()), maxOccurs - minOccurs, maxOccurs - minOccurs, accept) }, accept);
                    //Debug.Assert(null != result.FirstAcceptingState);
                    return(result);
                }
            }
            // should never get here
            throw new NotImplementedException();
        }