예제 #1
0
            public static FA From(string sequence)
            {
                Debug.Assert(!string.IsNullOrEmpty(sequence));

                var start   = new State();
                var current = start;
                var next    = (State?)null;

                foreach (var ch in sequence)
                {
                    next = new State();
                    current.Add(Integers.From(ch), next);
                    current = next;
                }

                Debug.Assert(next != null);
                return(FA.From(start, next));
            }
예제 #2
0
            public static FA Complete(FA dfa)
            {
                EnsureDfa(dfa);

                State?sink = null;

                foreach (var state in dfa.States)
                {
                    var rest = UnicodeSets.Any();

                    foreach (var transition in state.Transitions)
                    {
                        rest = rest.ExceptWith(transition.Set);
                    }

                    if (!rest.IsEmpty)
                    {
                        if (sink == null)
                        {
                            sink = new State();
                            sink.Add(Integers.Any, sink);
                        }

                        state.Add(Integers.From(rest), sink);
                    }
                }

                if (sink != null)
                {
                    sink.Id = dfa.States.Count;
                    dfa.States.Add(sink);
                }

                EnsureComplete(dfa);

                return(dfa);
            }
예제 #3
0
            public static FA ToDfa(FA nfa)
            {
                if (nfa.Final == null)
                {
                    EnsureDfa(nfa);
                    return(nfa);
                }

                var once  = new UniqueQueue <Closure>();
                var start = new Closure(nfa.Start, nfa.Final);

                once.Enqueue(start);

                while (once.Count > 0)
                {
                    var closure     = once.Dequeue();
                    var transitions = closure.UnambiguateTransitions();

                    foreach (var transition in transitions)
                    {
                        var terminal      = transition.Key;
                        var targets       = transition.Value;
                        var targetClosure = new Closure(targets, nfa.Final);
                        once.Enqueue(targetClosure, out targetClosure);
                        var target = targetClosure.DfaState;

                        closure.DfaState.Add(Integers.From(terminal), target);
                    }
                }

                var dfa = From(start.DfaState);

                EnsureDfa(dfa);

                return(dfa);
            }
예제 #4
0
                public static FA Build(FA dfa1, FA dfa2, Func <State, State, bool> isFinal)
                {
                    EnsureDfa(dfa1);
                    EnsureDfa(dfa2);

                    dfa1 = Complete(dfa1);
                    dfa2 = Complete(dfa2);

                    EnsureComplete(dfa1);
                    EnsureComplete(dfa2);

                    var cross = new State[dfa1.States.Count, dfa2.States.Count];

                    var t1 = dfa1.States.Select(s => GetTransitions(s)).ToList();
                    var t2 = dfa2.States.Select(s => GetTransitions(s)).ToList();

                    for (var n1 = 0; n1 < dfa1.States.Count; n1 += 1)
                    {
                        var state1 = dfa1.States[n1];

                        for (var n2 = 0; n2 < dfa2.States.Count; n2 += 1)
                        {
                            var state2 = dfa2.States[n2];

                            var newState = new State(isFinal(state1, state2));
                            if (state1.IsPayload && !state2.IsPayload)
                            {
                                newState.AddPayload(state1);
                            }
                            else if (!state1.IsPayload && state2.IsPayload)
                            {
                                newState.AddPayload(state2);
                            }
                            else if (state1.IsPayload && state2.IsPayload)
                            {
                                Debug.Assert(true);
#if true
                                if (state1.Transitions.Count == 1 && state1.Transitions[0].Set.IsAny)
                                {
                                    newState.AddPayload(state1);
                                }
                                else if (state2.Transitions.Count == 1 && state2.Transitions[0].Set.IsAny)
                                {
                                    newState.AddPayload(state2);
                                }
                                else
                                {
                                    if (state1.Payload > state2.Payload)
                                    {
                                        newState.AddPayload(state1);
                                    }
                                    else
                                    {
                                        newState.AddPayload(state2);
                                    }
                                    //throw new InternalException("missing tie break");
                                }
#endif
                            }

                            cross[n1, n2] = newState;
                        }
                    }

                    for (var n1 = 0; n1 < dfa1.States.Count; n1 += 1)
                    {
                        for (var n2 = 0; n2 < dfa2.States.Count; n2 += 1)
                        {
                            var state    = cross[n1, n2];
                            var ctranses = GetMerge(t1[n1], t2[n2]);
                            foreach (var ctrans in ctranses)
                            {
                                state.Add(Integers.From(ctrans.Range.Min, ctrans.Range.Max), cross[ctrans.Target1, ctrans.Target2]);
                            }
                        }
                    }

                    var dfa = From(cross[0, 0]);

                    EnsureComplete(dfa);

                    dfa = dfa.RemoveDead();

                    dfa = dfa.Minimize();

                    dfa = dfa.RemoveDead();

                    return(dfa);
                }
예제 #5
0
 public static FA From(int first, int last) => Single(Integers.From(first, last));
예제 #6
0
 public static FA From(char ch) => Single(Integers.From(ch));