Exemplo n.º 1
0
 public static Dfa <TSymbol> ProductDfa(DfaUtils.MinimizedDfa <TSymbol>[] dfas)
 {
     if (dfas.Length == 0)
     {
         throw new ArgumentException();
     }
     else if (dfas.Length == 1)
     {
         return(new Dfa <TSymbol>(dfas[0]));
     }
     else
     {
         DfaUtils.MinimizedDfa <TSymbol> cur = dfas[0];
         for (int i = 1; i < dfas.Length; i++)
         {
             cur = DfaUtils.MakeMinimizedProductDfa <
                 DfaUtils.MinimizedDfa <TSymbol>,
                 DfaUtils.MinimizedDfaState <TSymbol>,
                 DfaUtils.MinimizedDfa <TSymbol>,
                 DfaUtils.MinimizedDfaState <TSymbol>,
                 TSymbol
                 >(cur, dfas[i], new DfaUtils.AmbiguityHandler(MaxAmbiguityHandler));
         }
         return(new Dfa <TSymbol>(cur));
     }
 }
Exemplo n.º 2
0
        //1:0 --a--> 2
        //2:1 --a--> 3
        //3:2 --a--> 2
        public void SimpleTest2()
        {
            var firstState = new DfaUtils.MinimizedDfaState <char>();

            firstState._accepting = 0;
            var secondState = new DfaUtils.MinimizedDfaState <char>();

            secondState._accepting = 1;
            var thirdState = new DfaUtils.MinimizedDfaState <char>();

            thirdState._accepting   = 2;
            firstState._transitions = new KeyValuePair <char, DfaUtils.MinimizedDfaState <char> >[1] {
                new KeyValuePair <char, DfaUtils.MinimizedDfaState <char> >('a', secondState)
            };
            secondState._transitions = new KeyValuePair <char, DfaUtils.MinimizedDfaState <char> >[1] {
                new KeyValuePair <char, DfaUtils.MinimizedDfaState <char> >('a', thirdState)
            };
            thirdState._transitions = new KeyValuePair <char, DfaUtils.MinimizedDfaState <char> >[1] {
                new KeyValuePair <char, DfaUtils.MinimizedDfaState <char> >('a', secondState)
            };
            var dfa = new DfaUtils.MinimizedDfa <char>();

            dfa._start = firstState;


            dfa = DfaUtils.Minimized <DfaUtils.MinimizedDfa <char>, DfaUtils.MinimizedDfaState <char>, char>(dfa);


            var stateList = DfaUtils.PrepareStateList <DfaUtils.MinimizedDfa <char>, DfaUtils.MinimizedDfaState <char>, char>(dfa);

            Assert.AreEqual(stateList.Count, 3);
        }
Exemplo n.º 3
0
        public static IReadOnlyDictionary <DfaAndState <Symbol>, IReadOnlyCollection <Symbol> > GetFirstSymbols(
            CompiledGrammar <Symbol> grammar,
            IReadOnlyCollection <DfaAndState <Symbol> > nullables)
        {
            var nullablesSet = new HashSet <DfaAndState <Symbol> >(nullables);

            var firstSymbols = new Dictionary <DfaAndState <Symbol>, HashSet <Symbol> >();
            var graph        = new Dictionary <DfaAndState <Symbol>, List <DfaAndState <Symbol> > >();

            foreach (var rule in grammar.Rules)
            {
                var dfa = rule.Value;
                foreach (var state in DfaUtils.GetAllStates(dfa))
                {
                    var stateEntity = StateEntity(dfa, state);
                    firstSymbols[stateEntity] = new HashSet <Symbol>();
                    graph[stateEntity]        = new List <DfaAndState <Symbol> >();

                    foreach (var transition in dfa.Transitions(state))
                    {
                        Symbol symbol    = transition.Key;
                        var    nextState = transition.Value;
                        if (dfa.Label(nextState).IsNone() && dfa.IsStable(nextState))
                        {
                            continue;
                        }

                        firstSymbols[stateEntity].Add(symbol);

                        if (!grammar.Rules.ContainsKey(symbol))
                        {
                            continue;
                        }

                        var symbolEntity = StateEntity(grammar.Rules[symbol], grammar.Rules[symbol].StartingState());
                        graph[stateEntity].Add(symbolEntity);

                        if (nullablesSet.Contains(symbolEntity))
                        {
                            graph[stateEntity].Add(StateEntity(dfa, transition.Value));
                        }
                    }
                }
            }

            TransitiveClosure(graph, firstSymbols);

            return(firstSymbols.ToDictionary(kpv => kpv.Key, kpv => kpv.Value as IReadOnlyCollection <Symbol>));
        }
Exemplo n.º 4
0
        public static DfaUtils.MinimizedDfa <TSymbol> RegexDfa(RegEx <TSymbol> RegEx, uint acceptingStateMarker)
        {
            if (acceptingStateMarker == 0)
            {
                throw new ArgumentOutOfRangeException();
            }
            AbstractDfa <DFAState <TSymbol>, TSymbol> factorDfa =
                (AbstractDfa <DFAState <TSymbol>, TSymbol>) new RegExDfa <TSymbol>(RegEx, acceptingStateMarker);

            return(DfaUtils.MakeMinimizedProductDfa <
                       AbstractDfa <DFAState <TSymbol>, TSymbol>,
                       DFAState <TSymbol>,
                       AbstractDfa <DFAState <TSymbol>, TSymbol>,
                       DFAState <TSymbol>,
                       TSymbol
                       >(factorDfa, factorDfa, new DfaUtils.AmbiguityHandler(MaxAmbiguityHandler)));
        }
Exemplo n.º 5
0
        public void MakeMinimizedProductDfaTypePunnedInvocation()
        {
            IDfa <char> someDfa      = DfaUtils.MakeEmptyLanguageDfa <char>();
            var         someOtherDfa = DfaUtils.MakeMinimizedProductDfa(someDfa, someDfa,
                                                                        (a, b) =>
            {
                if (a != 0 && b != 0)
                {
                    throw new ArgumentException();
                }
                return(a + b);
            });

            Assert.NotNull(someOtherDfa);
            Assert.NotNull(someOtherDfa.Start);
            Assert.AreEqual(someOtherDfa.Start.Accepting, 0);
            Assert.AreEqual(someOtherDfa.Start.Transitions.Count, 1);
            Assert.AreEqual(someOtherDfa.Start.Transitions[0].Key, '\0');
            Assert.AreSame(someOtherDfa.Start.Transitions[0].Value, someOtherDfa.Start);
        }
Exemplo n.º 6
0
        public static IReadOnlyDictionary <DfaAndState <TLabel>, IReadOnlyCollection <TLabel> > GetFollowSymbols(
            CompiledGrammar <TLabel> grammar,
            IReadOnlyCollection <DfaAndState <TLabel> > nullables,
            IReadOnlyDictionary <TLabel, IReadOnlyCollection <DfaAndState <TLabel> > > first,
            TLabel eofSymbol)
        {
            var resultSymbols = new Dictionary <TLabel, HashSet <TLabel> >();

            GetDefault(resultSymbols, grammar.StartSymbol).Add(eofSymbol);

            var resultStates = new Dictionary <DfaAndState <TLabel>, HashSet <TLabel> >();

            while (true)
            {
                bool anythingChanged = false;

                foreach (var rule in grammar.Rules)
                {
                    var dfa = rule.Value;

                    foreach (var state in DfaUtils.GetAllStates(dfa))
                    {
                        var label       = dfa.Label(state);
                        var dfaAndState = new DfaAndState <TLabel> {
                            Dfa = dfa, State = state
                        };
                        var stateFollows = GetDefault(resultStates, dfaAndState);

                        if (label.IsSome())
                        {
                            var symFollows = GetDefault(resultSymbols, label.Get().Lhs);

                            foreach (var sym in symFollows)
                            {
                                anythingChanged = stateFollows.Add(sym) || anythingChanged;
                            }
                        }

                        foreach (var transition in dfa.Transitions(state))
                        {
                            TLabel edgeSymbol = transition.Key;

                            var nextState       = transition.Value;
                            var nextDfaAndState = new DfaAndState <TLabel> {
                                Dfa = dfa, State = nextState
                            };
                            if (dfa.Label(nextState).IsNone() && dfa.IsStable(nextState))
                            {
                                continue;
                            }

                            anythingChanged = stateFollows.Add(edgeSymbol) || anythingChanged;

                            // And also add First (first is the same as Follow of the initial state)
                            if (grammar.Rules.ContainsKey(edgeSymbol))
                            {
                                var edgeStartState = new DfaAndState <TLabel> {
                                    Dfa = grammar.Rules[edgeSymbol]
                                };
                                edgeStartState.State = edgeStartState.Dfa.StartingState();
                                foreach (var sym in GetDefault(resultStates, edgeStartState))
                                {
                                    anythingChanged = stateFollows.Add(sym) || anythingChanged;
                                }
                            }

                            var edgeFollows = GetDefault(resultSymbols, edgeSymbol);
                            foreach (var sym in GetDefault(resultStates, nextDfaAndState))
                            {
                                anythingChanged = edgeFollows.Add(sym) || anythingChanged;
                            }
                        }
                    }
                }

                if (!anythingChanged)
                {
                    break;
                }
            }

            var resultStatesCorrect = new Dictionary <DfaAndState <TLabel>, HashSet <TLabel> >();

            // Contrary to expectations, resultStates doesn't contain correct follows for accepting states of the automatas,
            // because they can be reused.
            // To sum up: 'follow for states' doesn't make sense, only for symbols, but we fake 'follow for states' to conform with the API.
            foreach (var rule in grammar.Rules)
            {
                var dfa = rule.Value;

                foreach (var state in DfaUtils.GetAllStates(dfa))
                {
                    var label       = dfa.Label(state);
                    var dfaAndState = new DfaAndState <TLabel> {
                        Dfa = dfa, State = state
                    };
                    var stateFollows = GetDefault(resultStates, dfaAndState);

                    if (label.IsSome())
                    {
                        resultStatesCorrect[dfaAndState] = resultSymbols[label.Get().Lhs];
                    }
                }
            }

            return(resultStatesCorrect.ToDictionary(kpv => kpv.Key, kpv => kpv.Value as IReadOnlyCollection <TLabel>));
        }
Exemplo n.º 7
0
 public void MinimizedEmpty()
 {
     DfaUtils.MakeEmptyLanguageDfa <char>();
 }