Exemplo n.º 1
0
        /// <summary>
        /// Creates an FA that will match any one of a set of a characters
        /// </summary>
        /// <param name="ranges">The set ranges of characters that will be matched</param>
        /// <param name="accept">The symbol to accept</param>
        /// <returns>An FA that will match the specified set</returns>
        public static CharFA <TAccept> Set(IEnumerable <CharRange> ranges, TAccept accept = default(TAccept))
        {
            var result = new CharFA <TAccept>();
            var final  = new CharFA <TAccept>(true, accept);

            foreach (var ch in CharRange.ExpandRanges(ranges))
            {
                result.Transitions.Add(ch, final);
            }
            return(result);
        }
Exemplo n.º 2
0
 static IEnumerable <CharRange> _ParseRanges(IEnumerable <char> charRanges, bool normalize)
 {
     if (!normalize)
     {
         return(_ParseRanges(charRanges));
     }
     else
     {
         var result = new List <CharRange>(_ParseRanges(charRanges));
         CharRange.NormalizeRangeList(result);
         return(result);
     }
 }
Exemplo n.º 3
0
 /// <summary>
 /// Returns a <see cref="IDictionary{FA,IList{KeyValuePair{Char,Char}}}"/>, keyed by state, that contains all of the outgoing local input transitions, expressed as a series of ranges
 /// </summary>
 /// <param name="result">The <see cref="IDictionary{FA,IList{CharRange}}"/> to fill, or null to create one.</param>
 /// <returns>A <see cref="IDictionary{FA,IList{CharRange}}"/> containing the result of the query</returns>
 public IDictionary <FA <char, TAccept>, IList <CharRange> > FillInputTransitionRangesGroupedByState(IDictionary <FA <char, TAccept>, IList <CharRange> > result = null)
 {
     if (null == result)
     {
         result = new Dictionary <FA <char, TAccept>, IList <CharRange> >();
     }
     // using the optimized dictionary we have little to do here.
     foreach (var trns in (IDictionary <FA <char, TAccept>, ICollection <char> >)Transitions)
     {
         result.Add(trns.Key, new List <CharRange>(CharRange.GetRanges(trns.Value)));
     }
     return(result);
 }
Exemplo n.º 4
0
 public static void _AppendRangeTo(StringBuilder builder, CharRange range)
 {
     _AppendRangeCharTo(builder, range.First);
     if (0 == range.Last.CompareTo(range.First))
     {
         return;
     }
     if (range.Last == range.First + 1)             // spit out 1 length ranges as two chars
     {
         _AppendRangeCharTo(builder, range.Last);
         return;
     }
     builder.Append('-');
     _AppendRangeCharTo(builder, range.Last);
 }
Exemplo n.º 5
0
        public new CharDfaEntry[] ToDfaTable(IDictionary <TAccept, int> symbolLookup = null)
        {
            var dfa     = ToDfa();
            var closure = dfa.FillClosure();

            if (null == symbolLookup)
            {
                symbolLookup = new ListDictionary <TAccept, int>();
                var i = 0;
                for (int jc = closure.Count, j = 0; j < jc; ++j)
                {
                    var fa = closure[j];
                    if (fa.IsAccepting && !symbolLookup.ContainsKey(fa.AcceptSymbol))
                    {
                        symbolLookup.Add(fa.AcceptSymbol, i);
                        ++i;
                    }
                }
            }
            var result = new CharDfaEntry[closure.Count];

            for (var i = 0; i < result.Length; i++)
            {
                var fa   = closure[i];
                var trgs = ((CharFA <TAccept>)fa).FillInputTransitionRangesGroupedByState();
                var trns = new KeyValuePair <string, int> [trgs.Count];
                var j    = 0;

                foreach (var trg in trgs)
                {
                    trns[j] = new KeyValuePair <string, int>(
                        CharRange.ToPackedString(trg.Value),
                        closure.IndexOf(trg.Key));

                    ++j;
                }
                result[i] = new CharDfaEntry(
                    fa.IsAccepting ? symbolLookup[fa.AcceptSymbol] : -1,
                    trns);
            }
            return(result);
        }
Exemplo n.º 6
0
        static CharFA <TAccept> _Parse(ParseContext pc, TAccept accept)
        {
            CharFA <TAccept> result = new CharFA <TAccept>(true, accept);

            CharFA <TAccept> f, next;
            int ch;

            pc.EnsureStarted();
            var current = result;

            while (true)
            {
                switch (pc.Current)
                {
                case -1:
                    return(result);

                case '.':
                    pc.Advance();
                    f = current.FirstAcceptingState as CharFA <TAccept>;

                    current = Set(new CharRange[] { new CharRange(char.MinValue, char.MaxValue) }, accept);
                    switch (pc.Current)
                    {
                    case '*':
                        current = Kleene(current, accept);
                        pc.Advance();
                        break;

                    case '+':
                        current = Repeat(current, accept);
                        pc.Advance();
                        break;

                    case '?':
                        current = Optional(current, accept);
                        pc.Advance();
                        break;
                    }
                    f.IsAccepting = false;
                    f.EpsilonTransitions.Add(current);
                    break;

                case '\\':
                    if (-1 != (ch = _ParseEscape(pc)))
                    {
                        next = null;
                        switch (pc.Current)
                        {
                        case '*':
                            next = new CharFA <TAccept>();
                            next.Transitions.Add((char)ch, new CharFA <TAccept>(true, accept));
                            next = Kleene(next, accept);
                            pc.Advance();
                            break;

                        case '+':
                            next = new CharFA <TAccept>();
                            next.Transitions.Add((char)ch, new CharFA <TAccept>(true, accept));
                            next = Repeat(next, accept);
                            pc.Advance();
                            break;

                        case '?':
                            next = new CharFA <TAccept>();
                            next.Transitions.Add((char)ch, new CharFA <TAccept>(true, accept));
                            next = Optional(next, accept);
                            pc.Advance();
                            break;

                        default:
                            current             = current.FirstAcceptingState as CharFA <TAccept>;
                            current.IsAccepting = false;
                            current.Transitions.Add((char)ch, new CharFA <TAccept>(true, accept));
                            break;
                        }
                        if (null != next)
                        {
                            current             = current.FirstAcceptingState as CharFA <TAccept>;
                            current.IsAccepting = false;
                            current.EpsilonTransitions.Add(next);
                            current = next;
                        }
                    }
                    else
                    {
                        pc.Expecting();                              // throw an error
                        return(null);                                // doesn't execute
                    }
                    break;

                case ')':
                    return(result);

                case '(':
                    pc.Advance();
                    pc.Expecting();
                    f       = current.FirstAcceptingState as CharFA <TAccept>;
                    current = _Parse(pc, accept);
                    pc.Expecting(')');
                    pc.Advance();
                    switch (pc.Current)
                    {
                    case '*':
                        current = Kleene(current, accept);
                        pc.Advance();
                        break;

                    case '+':
                        current = Repeat(current, accept);
                        pc.Advance();
                        break;

                    case '?':
                        current = Optional(current, accept);
                        pc.Advance();
                        break;
                    }
                    var ff = f.FirstAcceptingState;
                    ff.EpsilonTransitions.Add(current);
                    ff.IsAccepting = false;
                    break;

                case '|':
                    if (-1 != pc.Advance())
                    {
                        current = _Parse(pc, accept);
                        result  = Or(new CharFA <TAccept>[] { result as CharFA <TAccept>, current as CharFA <TAccept> }, accept);
                    }
                    else
                    {
                        current = current.FirstAcceptingState as CharFA <TAccept>;
                        result  = Optional(result, accept);
                    }
                    break;

                case '[':
                    pc.ClearCapture();
                    pc.Advance();
                    pc.Expecting();
                    bool not = false;
                    if ('^' == pc.Current)
                    {
                        not = true;
                        pc.Advance();
                        pc.Expecting();
                    }
                    pc.TryReadUntil(']', '\\', false);
                    pc.Expecting(']');
                    pc.Advance();

                    var r = (!not && "." == pc.Capture) ?
                            new CharRange[] { new CharRange(char.MinValue, char.MaxValue) } :
                    _ParseRanges(pc.Capture, true);
                    if (not)
                    {
                        r = CharRange.NotRanges(r);
                    }
                    f       = current.FirstAcceptingState as CharFA <TAccept>;
                    current = Set(r, accept);
                    switch (pc.Current)
                    {
                    case '*':
                        current = Kleene(current, accept);
                        pc.Advance();
                        break;

                    case '+':
                        current = Repeat(current, accept);
                        pc.Advance();
                        break;

                    case '?':
                        current = Optional(current, accept);
                        pc.Advance();
                        break;
                    }
                    f.IsAccepting = false;
                    f.EpsilonTransitions.Add(current);
                    break;

                default:
                    ch = pc.Current;
                    pc.Advance();
                    next = null;
                    switch (pc.Current)
                    {
                    case '*':
                        next = new CharFA <TAccept>();
                        next.Transitions.Add((char)ch, new CharFA <TAccept>(true, accept));
                        next = Kleene(next, accept);
                        pc.Advance();
                        break;

                    case '+':
                        next = new CharFA <TAccept>();
                        next.Transitions.Add((char)ch, new CharFA <TAccept>(true, accept));
                        next = Repeat(next, accept);
                        pc.Advance();
                        break;

                    case '?':
                        next = new CharFA <TAccept>();

                        next.Transitions.Add((char)ch, new CharFA <TAccept>(true, accept));
                        next = Optional(next, accept);
                        pc.Advance();
                        break;

                    default:
                        current             = current.FirstAcceptingState as CharFA <TAccept>;
                        current.IsAccepting = false;
                        current.Transitions.Add((char)ch, new CharFA <TAccept>(true, accept));
                        break;
                    }
                    if (null != next)
                    {
                        current             = current.FirstAcceptingState as CharFA <TAccept>;
                        current.IsAccepting = false;
                        current.EpsilonTransitions.Add(next);
                        current = next;
                    }
                    break;
                }
            }
        }