public void RemoveTransition(CharRange input)
            {
                // overlaps
                // doesn't overlap
                // throw new NotImplementedException();

                transitions.Remove(input);
                Minimize();
            }
예제 #2
0
            public void AddTransition(CharRange input, State to)
            {
                if (!transitions.ContainsKey(input))
                {
                    transitions[input] = new HashSet <State>();
                }

                transitions[input].Add(to);
            }
            public void AddTransition(CharRange input, State to)
            {
                if (transitions.Keys.Any(range => range.Overlaps(input)))
                {
                    throw new ArgumentOutOfRangeException("Already have a transition for this input or it's overlapping", "input");
                }

                transitions[input] = to;

                Minimize();
            }
예제 #4
0
        public static NFA Char(CharRange c)
        {
            NFA nfa = new NFA();

            nfa.Start = new State();
            nfa.Exit  = new State()
            {
                IsFinal = true
            };
            nfa.Start.AddTransition(c, nfa.Exit);
            return(nfa);
        }
예제 #5
0
 public IEnumerable <State> this[CharRange input]
 {
     get
     {
         foreach (CharRange range in transitions.Keys.OrderBy(r => r))
         {
             if (range.Contains(input))
             {
                 return(transitions[range]);
             }
         }
         return(null);
     }
 }
            public void Minimize()
            {
                // todo: join ranges, maybe?

                // this makes it so much faster!!!!!
                var sorted = transitions.OrderBy(kp => kp.Key).ToArray();

                ranges = sorted.Select(kp => kp.Key).ToArray();
                states = sorted.Select(kp => kp.Value).ToArray();
                count  = ranges.Length;
                if (count > 0)
                {
                    firstRange = ranges[0];
                }
            }
        public void Load(Stream stream)
        {
            Dictionary <int, State> states = new Dictionary <int, State>();

            using (BinaryReader reader = new BinaryReader(stream, System.Text.Encoding.UTF8, leaveOpen: true))
            {
                int stateCount = reader.ReadInt32();

                for (int i = 0; i < stateCount; i++)
                {
                    int   id         = reader.ReadInt32();
                    bool  isFinal    = reader.ReadBoolean();
                    int   valueCount = reader.ReadInt32();
                    int[] values     = new int[valueCount];
                    for (int v = 0; v < valueCount; v++)
                    {
                        values[v] = reader.ReadInt32();
                    }
                    states[id] = new State {
                        IsFinal = isFinal, Values = values
                    };
                }

                for (int i = 0; i < stateCount; i++)
                {
                    int transitionCount = reader.ReadInt32();

                    for (int t = 0; t < transitionCount; t++)
                    {
                        CharRange input     = new CharRange(reader.ReadChar(), reader.ReadChar());
                        int       fromState = reader.ReadInt32();
                        int       toState   = reader.ReadInt32();
                        states[fromState].AddTransition(input, states[toState]);
                    }
                }

                int startState = reader.ReadInt32();
                if (startState != -1)
                {
                    Start = states[startState];
                }
            }
        }
            public State this[char c]
            {
                // this is the hottest code
                // it gets called a gazillion times
                get
                {
                    if (count == 0)
                    {
                        return(null);
                    }
                    if (count == 1)
                    {
                        return(c >= firstRange.From && c <= firstRange.To ? states[0] : null);
                    }

                    int low  = 0;
                    int high = count - 1;

                    while (low <= high)
                    {
                        int       mid   = low + (high - low) / 2;
                        CharRange range = ranges[mid];

                        if (c >= range.From && c <= range.To)
                        {
                            return(states[mid]);
                        }

                        if (range.From < c)
                        {
                            low = mid + 1;
                        }
                        else
                        {
                            high = mid - 1;
                        }
                    }

                    return(null);
                }
            }
            public void SetTransition(CharRange input, State to) // not used by NFA.ToDfa()
            {
                CharRange overlaping = transitions.Keys.SingleOrDefault(range => range.Overlaps(input));

                if (overlaping == CharRange.Empty) // [a..c -> 1] + [d..f -> 2]
                {
                    transitions[input] = to;
                }
                else // [a..z -> 1] + [c..f -> 2] = [a..b -> 1] + [c..f -> 2] + [g..z -> 1]
                {
                    State overlapingState = transitions[overlaping];
                    transitions.Remove(overlaping);

                    CharRange[] ranges = overlaping.Split(input);
                    foreach (CharRange range in ranges)
                    {
                        transitions[range] = range.Overlaps(input) ? to : overlapingState;
                    }
                }

                Minimize();
            }