Beispiel #1
0
        /// <summary>
        /// Creates a new FA that matches the specified FA expression or empty
        /// </summary>
        /// <param name="expr">The expression to make optional</param>
        /// <param name="accept">The symbol to accept</param>
        /// <returns>A new FA that will match the specified expression or empty</returns>
        public static CharFA <TAccept> Optional(CharFA <TAccept> expr, TAccept accept = default(TAccept))
        {
            var result = expr.Clone();
            var f      = result.FirstAcceptingState;

            f.AcceptSymbol = accept;
            result.EpsilonTransitions.Add(f);
            return(result);
        }
Beispiel #2
0
        /// <summary>
        /// Creates a new FA that will match a repetition of the specified FA expression
        /// </summary>
        /// <param name="expr">The expression to repeat</param>
        /// <param name="minOccurs">The minimum number of times to repeat or -1 for unspecified (0)</param>
        /// <param name="maxOccurs">The maximum number of times to repeat or -1 for unspecified (unbounded)</param>
        /// <param name="accept">The symbol to accept</param>
        /// <returns>A new FA that matches the specified FA one or more times</returns>
        public static CharFA <TAccept> Repeat(CharFA <TAccept> expr, int minOccurs = -1, int maxOccurs = -1, TAccept accept = default(TAccept))
        {
            expr = expr.Clone();
            if (minOccurs > 0 && maxOccurs > 0 && minOccurs > maxOccurs)
            {
                throw new ArgumentOutOfRangeException(nameof(maxOccurs));
            }
            switch (minOccurs)
            {
            case -1:
            case 0:
                switch (maxOccurs)
                {
                case -1:
                case 0:
                    var result = new CharFA <TAccept>();
                    var final  = new CharFA <TAccept>(true, accept);
                    final.EpsilonTransitions.Add(result);
                    foreach (var afa in expr.FillAccepting())
                    {
                        afa.IsAccepting = false;
                        afa.EpsilonTransitions.Add(final);
                    }
                    result.EpsilonTransitions.Add(expr);
                    result.EpsilonTransitions.Add(final);
                    return(result);

                case 1:
                    return(Optional(expr, accept));

                default:
                    var l = new List <CharFA <TAccept> >();
                    expr = Optional(expr);
                    l.Add(expr);
                    for (int i = 1; i < maxOccurs; ++i)
                    {
                        l.Add(expr.Clone());
                    }
                    return(Concat(l, accept));
                }

            case 1:
                switch (maxOccurs)
                {
                case -1:
                case 0:
                    var result = new CharFA <TAccept>();
                    var final  = new CharFA <TAccept>(true, accept);
                    final.EpsilonTransitions.Add(result);
                    foreach (var afa in expr.FillAccepting())
                    {
                        afa.IsAccepting = false;
                        afa.EpsilonTransitions.Add(final);
                    }
                    result.EpsilonTransitions.Add(expr);
                    return(result);

                case 1:
                    return(expr);

                default:
                    return(Concat(new CharFA <TAccept>[] { expr, Repeat(expr.Clone(), 0, maxOccurs - 1) }, accept));
                }

            default:
                switch (maxOccurs)
                {
                case -1:
                case 0:
                    return(Concat(new CharFA <TAccept>[] { Repeat(expr, minOccurs, minOccurs, accept), Repeat(expr, 0, 0, accept) }, accept));

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

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