Esempio n. 1
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)
                    {
                        for (var n2 = 0; n2 < dfa2.States.Count; n2 += 1)
                        {
                            cross[n1, n2] = new State(isFinal(dfa1.States[n1], dfa2.States[n2]));
                        }
                    }

                    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(Codepoints.From(ctrans.Range.Min, ctrans.Range.Max), cross[ctrans.Target1, ctrans.Target2]);
                            }
                        }
                    }

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

                    EnsureComplete(dfa);

                    return(dfa.RemoveDead().Minimize());
                }
Esempio n. 2
0
            private static void EnsureComplete(FA dfa)
            {
                EnsureDfa(dfa);

                foreach (var state in dfa.States)
                {
                    var all = new Codepoints();
                    var sum = 0;
                    foreach (var transition in state.Transitions)
                    {
                        sum += transition.Terminal.Cardinality;
                        all.Add(transition.Terminal);
                    }
                    if (!UnicodeSets.IsAny(all))
                    {
                        throw new Exception("DFA: incomplete transition set (DFA is not `complete´)");
                    }
                    if (sum != all.Cardinality)
                    {
                        throw new Exception("DFA: overlapping transitions (DFA is not `sane´)");
                    }
                }
            }
Esempio n. 3
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.Terminal);
                    }

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

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

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

                EnsureComplete(dfa);

                return(dfa);
            }
Esempio n. 4
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(Codepoints.From(terminal), target);
                    }
                }

                var dfa = From(start.DfaState);

                EnsureDfa(dfa);

                return(dfa);
            }
Esempio n. 5
0
 private Codepoints(Codepoints other)
     : this(other.ranges)
 {
 }
Esempio n. 6
0
 public void Add(Codepoints terminal, State target)
 {
     Transitions.Add(new Transition(terminal, target));
 }