public void RemoveTransition(CharRange input) { // overlaps // doesn't overlap // throw new NotImplementedException(); transitions.Remove(input); Minimize(); }
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(); }
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); }
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(); }