Пример #1
0
        public static IReadOnlyCollection <IState> GetAllStates <TLabel, Symbol>(this IDfa <TLabel, Symbol> dfa)
        {
            var visited = new HashSet <IState>();
            var queue   = new Queue <IState>();

            queue.Enqueue(dfa.StartingState());
            visited.Add(dfa.StartingState());

            while (queue.Count > 0)
            {
                var s           = queue.Dequeue();
                var transitions = dfa.Transitions(s);

                foreach (var nextState in transitions.Values)
                {
                    if (!visited.Contains(nextState))
                    {
                        queue.Enqueue(nextState);
                        visited.Add(nextState);
                    }
                }
            }

            return(visited);
        }
Пример #2
0
        internal static int NumberOfPseudoDeadStates(this IDfa <char> dfa)
        {
            int number = 0;
            Queue <IDfaState <char> >          Q     = new Queue <IDfaState <char> >();
            Dictionary <IDfaState <char>, int> color = new Dictionary <IDfaState <char>, int>();

            Q.Enqueue(dfa.Start);

            while (Q.Count > 0)
            {
                IDfaState <char> current_state = Q.Dequeue();
                if (!color.ContainsKey(current_state))
                {
                    color[current_state] = 1;
                    if (current_state.IsPseudoDead())
                    {
                        number++;
                    }
                    foreach (var transition in current_state.Transitions)
                    {
                        if (!color.ContainsKey(transition.Value))
                        {
                            Q.Enqueue(transition.Value);
                        }
                    }
                }
            }
            return(number);
        }
Пример #3
0
        private static IDfa <bool, TLabel> RegexToDfa(Regex <TLabel> regex)
        {
            INfa <TLabel> nfa = RegexToNfaConverter <TLabel> .Convert(regex);

            IDfa <bool, TLabel> dfa = NfaToDfaConverter <TLabel> .Convert(nfa);

            return(DfaMinimizer <bool, TLabel> .Minimize(dfa));
        }
Пример #4
0
 private void Call(IDfa <Optional <Rule <TLabel> >, TLabel> dfa, IState state, TLabel actionLabel)
 {
     this.statesStack.Pop();
     this.statesStack.Push(dfa.Transitions(state)[actionLabel]);
     this.dfaStack.Push(this.rules[actionLabel]);
     this.statesStack.Push(this.rules[actionLabel].StartingState());
     this.nodesStack.Push(new List <ParseTree <TLabel> >());
 }
Пример #5
0
            public MinimalDfa(IDfa <TLabel, Symbol> dfa, List <HashSet <IState> > statePartition)
            {
                this.dfa            = dfa;
                this.statePartition = statePartition;

                this.CreateStateMapping();
                this.FindStableStates();
            }
Пример #6
0
        private static DfaAndState <TLabel> CreateDfaAndState(IDfa <Optional <Rule <TLabel> >, TLabel> dfa, IState state)
        {
            var pair = new DfaAndState <TLabel>
            {
                Dfa   = dfa,
                State = state
            };

            return(pair);
        }
Пример #7
0
        public static IDfa <TSymbol> MakeMinimizedProductDfa <TSymbol>(IDfa <TSymbol> lastDfa, IDfa <TSymbol> newDfa,
                                                                       AmbiguityHandler handler)
            where TSymbol : IEquatable <TSymbol>, IComparable <TSymbol>
        {
            // This implementation assumes that all instances of IDfa are in fact instances of AbstractDfa
            var lastDfaType      = lastDfa.GetType();
            var newDfaType       = newDfa.GetType();
            var lastDfaStateType = lastDfa.Start.GetType();
            var newDfaStateType  = newDfa.Start.GetType();

            return((IDfa <TSymbol>)MakeMinimizedProductDfaMethod
                   .MakeGenericMethod(lastDfaType, lastDfaStateType, newDfaType, newDfaStateType, typeof(TSymbol))
                   .Invoke(null, new object[] { lastDfa, newDfa, handler }));
        }
Пример #8
0
        private static void CheckMinimization <TLabel>(IDfa <TLabel, char> dfa, int expectedNumberOfStates = -1)
        {
            var minimalDfa = DfaMinimizer <TLabel, char> .Minimize(dfa);

            var numberOfStates = ReachableStates(minimalDfa).Count;

            if (expectedNumberOfStates != -1)
            {
                Assert.AreEqual(expectedNumberOfStates, numberOfStates);
            }

            CheckAutomatonEquivalence(dfa, minimalDfa);
            CheckStateStability(minimalDfa);
        }
Пример #9
0
        // Be aware! The minimal dfa for the a given one will reuse some states!
        public static IDfa <TLabel, Symbol> Minimize(IDfa <TLabel, Symbol> dfa)
        {
            List <HashSet <IState> > partition = InitialPartition(dfa);

            while (true)
            {
                var newPartition = MooresStep(dfa, partition);
                if (PartitionRepresentation(partition) == PartitionRepresentation(newPartition))
                {
                    break;
                }

                partition = newPartition;
            }

            return(new MinimalDfa(dfa, partition));
        }
Пример #10
0
        private static TLabel GetTargetLabel <TLabel>(IDfa <TLabel, char> dfa, string s, TLabel defaultLabel)
        {
            var state = dfa.StartingState();

            foreach (var ch in s)
            {
                var transitions = dfa.Transitions(state);
                if (!transitions.ContainsKey(ch))
                {
                    return(defaultLabel);
                }

                state = transitions[ch];
            }

            return(dfa.Label(state));
        }
Пример #11
0
        private static void CheckStateStability <TLabel>(IDfa <TLabel, char> dfa)
        {
            foreach (var state in ReachableStates(dfa))
            {
                bool expectedStability = true;
                foreach (var(_, nextState) in dfa.Transitions(state))
                {
                    if (nextState != state)
                    {
                        expectedStability = false;
                        break;
                    }
                }

                Assert.AreEqual(expectedStability, dfa.IsStable(state), "Stability of the state is incorrect");
            }
        }
Пример #12
0
        public static bool AreEquivalent(IDfa <TLabel, Symbol> firstDfa, IDfa <TLabel, Symbol> secondDfa)
        {
            var reached = new HashSet <Tuple <IState, IState> >();
            var queue   = new Queue <Tuple <IState, IState> >();

            queue.Enqueue(Tuple.Create(firstDfa.StartingState(), secondDfa.StartingState()));
            reached.Add(queue.Peek());

            while (queue.Count > 0)
            {
                var(firstState, secondState) = queue.Dequeue();
                if (!firstDfa.Label(firstState).Equals(secondDfa.Label(secondState)))
                {
                    return(false);
                }

                var firstStateTransitions  = firstDfa.Transitions(firstState);
                var secondStateTransitions = secondDfa.Transitions(secondState);

                if (!firstStateTransitions.Count.Equals(secondStateTransitions.Count))
                {
                    return(false);
                }

                foreach (var(c, firstNextState) in firstStateTransitions)
                {
                    if (!secondStateTransitions.ContainsKey(c))
                    {
                        return(false);
                    }

                    var secondNextState = secondStateTransitions[c];

                    var pair = Tuple.Create(firstNextState, secondNextState);
                    if (!reached.Contains(pair))
                    {
                        reached.Add(pair);
                        queue.Enqueue(pair);
                    }
                }
            }

            return(true);
        }
Пример #13
0
        private static List <HashSet <IState> > MooresStep(IDfa <TLabel, Symbol> dfa, List <HashSet <IState> > partition)
        {
            var stateClassId = new Dictionary <IState, int>();

            for (int i = 0; i < partition.Count; ++i)
            {
                foreach (var state in partition[i])
                {
                    stateClassId[state] = i;
                }
            }

            var stateDerivatives = new List <Tuple <IState, List <int> > >();

            foreach (var equivalenceClass in partition)
            {
                foreach (var state in equivalenceClass)
                {
                    var derivative = new List <int> {
                        stateClassId[state]
                    };
                    derivative.AddRange(dfa.Transitions(state).OrderBy(t => t.Key).Select(t => stateClassId[t.Value]));
                    stateDerivatives.Add(Tuple.Create(state, derivative));
                }
            }

            var newPartition = new List <HashSet <IState> >();

            var groups = stateDerivatives.GroupBy(d => string.Join(" ", d.Item2.Select(t => Convert.ToString(t))));

            foreach (var group in groups)
            {
                var partitionGroup = new HashSet <IState>();
                foreach (var(state, _) in group)
                {
                    partitionGroup.Add(state);
                }

                newPartition.Add(partitionGroup);
            }

            return(newPartition);
        }
Пример #14
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);
        }
Пример #15
0
 private void Shift(
     ParseTree <TLabel> currentToken,
     IDfa <Optional <Rule <TLabel> >, TLabel> dfa,
     IState state,
     TLabel currentCategory,
     IEnumerator enumerator)
 {
     this.nodesStack.Peek().Add(currentToken);
     this.statesStack.Pop();
     this.statesStack.Push(dfa.Transitions(state)[currentCategory]);
     if (!enumerator.MoveNext())
     {
         this.diagnostics.Add(new Diagnostic(
                                  DiagnosticStatus.Error,
                                  PrematureEofDiagnosticType,
                                  "Parsing finished before reading all tokens",
                                  new List <Range>()));
         throw new ParseException("Premature EOF");
     }
 }
Пример #16
0
        private static List <HashSet <IState> > InitialPartition(IDfa <TLabel, Symbol> dfa)
        {
            var partition  = new List <HashSet <IState> >();
            var labelId    = new Dictionary <TLabel, int>();
            int labelCount = 0;

            foreach (IState state in ReachableStates(dfa))
            {
                TLabel stateLabel = dfa.Label(state);
                if (!labelId.ContainsKey(stateLabel))
                {
                    labelId.Add(stateLabel, labelCount);
                    partition.Add(new HashSet <IState>());
                    ++labelCount;
                }

                partition[labelId[stateLabel]].Add(state);
            }

            return(partition);
        }
Пример #17
0
        private static HashSet <IState> ReachableStates <TLabel>(IDfa <TLabel, char> dfa)
        {
            var reachedStates = new HashSet <IState>();

            var queue = new Queue <IState>(new[] { dfa.StartingState() });

            while (queue.Count > 0)
            {
                var state = queue.Dequeue();
                foreach (var(_, value) in dfa.Transitions(state))
                {
                    if (!reachedStates.Contains(value))
                    {
                        reachedStates.Add(value);
                        queue.Enqueue(value);
                    }
                }
            }

            return(reachedStates);
        }
Пример #18
0
        private static void CheckAutomatonEquivalence <TLabel>(IDfa <TLabel, char> firstDfa, IDfa <TLabel, char> secondDfa)
        {
            var reached = new HashSet <Tuple <IState, IState> >();
            var queue   = new Queue <Tuple <IState, IState> >();

            queue.Enqueue(Tuple.Create(firstDfa.StartingState(), secondDfa.StartingState()));
            reached.Add(queue.Peek());

            while (queue.Count > 0)
            {
                var(firstState, secondState) = queue.Dequeue();
                Assert.AreEqual(firstDfa.Label(firstState), secondDfa.Label(secondState), "Labels should be equal");
                var firstStateTransitions  = firstDfa.Transitions(firstState);
                var secondStateTransitions = secondDfa.Transitions(secondState);

                var firstTransitionCount  = firstStateTransitions.Count;
                var secondTransitionCount = secondStateTransitions.Count;
                Assert.AreEqual(
                    firstTransitionCount,
                    secondTransitionCount,
                    $"States {firstState} and {secondState} have different number of transitions: {firstTransitionCount} != {secondTransitionCount}");

                foreach (var(c, firstNextState) in firstStateTransitions)
                {
                    Assert.IsTrue(
                        secondStateTransitions.ContainsKey(c),
                        $"States have different sets of transitions, {secondTransitionCount} : {string.Join(",", firstStateTransitions.Select((x, y) => ((int)x.Key).ToString()).ToList())}");

                    var secondNextState = secondStateTransitions[c];

                    var pair = Tuple.Create(firstNextState, secondNextState);
                    if (!reached.Contains(pair))
                    {
                        reached.Add(pair);
                        queue.Enqueue(pair);
                    }
                }
            }
        }
Пример #19
0
        // tokenCategories - List of pair (Token, Regex for thie Token)
        public Lexer(
            IEnumerable <KeyValuePair <TLabel, string> > tokenCategories,
            TLabel eof,
            TLabel noneValue,
            Func <IEnumerable <TLabel>, TLabel> conflictSolver)
        {
            this.eof       = eof;
            this.noneValue = noneValue;
            var converter = new StringToRegexConverterFactory().CreateConverter();
            Dictionary <TLabel, IDfa <bool, char> > multipleDfa = tokenCategories.ToDictionary(
                x => x.Key,
                x =>
            {
                Regex <char> regex    = converter.Convert(x.Value);
                INfa <char> nfaPre    = RegexToNfaConverter <char> .Convert(regex);
                INfa <char> nfa       = ConcreteNfa <char> .CreateFromNfa(nfaPre);
                IDfa <bool, char> dfa = NfaToDfaConverter <char> .Convert(nfa);
                return(DfaMinimizer <bool, char> .Minimize(dfa));
            });
            var mergedDfa = DfaMerger <TLabel, char> .Merge(multipleDfa, conflictSolver);

            this.minimalizedDfa = DfaMinimizer <TLabel, char> .Minimize(mergedDfa);
        }
Пример #20
0
            private ParseTree <TLabel> Reduce(
                IDfa <Optional <Rule <TLabel> >, TLabel> dfa,
                IState state,
                ParseTree <TLabel> currentToken)
            {
                if (dfa.Label(state).IsNone())
                {
                    this.diagnostics.Add(new Diagnostic(
                                             DiagnosticStatus.Error,
                                             InvalidReduceActionDiagnosticType,
                                             "Invalid reduce action at {0}",
                                             new List <Range> {
                        currentToken.InputRange
                    }));
                    throw new ParseException("Invalid reduce action");
                }

                var rule                = dfa.Label(state).Get();
                var topNodes            = this.nodesStack.Peek();
                var newCategory         = rule.Lhs;
                var range               = GetRange(topNodes);
                ParseTree <TLabel> root = new Brunch <TLabel>
                {
                    Rule = rule, Children = topNodes, Category = newCategory, InputRange = range
                };

                this.statesStack.Pop();
                this.dfaStack.Pop();
                this.nodesStack.Pop();
                if (this.nodesStack.Count != 0)
                {
                    this.nodesStack.Peek().Add(root);
                }

                return(root);
            }
Пример #21
0
        private static HashSet <IState> ReachableStates(IDfa <TLabel, Symbol> dfa)
        {
            var reachedStates = new HashSet <IState>();

            var queue = new Queue <IState>();

            queue.Enqueue(dfa.StartingState());
            reachedStates.Add(dfa.StartingState());

            while (queue.Count > 0)
            {
                IState state = queue.Dequeue();
                foreach (KeyValuePair <Symbol, IState> transition in dfa.Transitions(state))
                {
                    if (!reachedStates.Contains(transition.Value))
                    {
                        reachedStates.Add(transition.Value);
                        queue.Enqueue(transition.Value);
                    }
                }
            }

            return(reachedStates);
        }
Пример #22
0
 private static DfaAndState <Symbol> StateEntity(IDfa <Optional <Rule <Symbol> >, Symbol> dfa, IState state)
 {
     return(new DfaAndState <Symbol> {
         Dfa = dfa, State = state
     });
 }
Пример #23
0
 public Lexer(IDfa <TLabel, char> dfa, TLabel eof)
 {
     this.minimalizedDfa = dfa;
     this.eof            = eof;
 }
Пример #24
0
        private static Dictionary <IState, Dictionary <TLabel, HashSet <IState> > > GetReverseTransitions(IDfa <Optional <Rule <TLabel> >, TLabel> dfa)
        {
            var allStates          = dfa.GetAllStates();
            var reverseTransitions = new Dictionary <IState, Dictionary <TLabel, HashSet <IState> > >();

            foreach (IState state in allStates)
            {
                reverseTransitions.Add(state, new Dictionary <TLabel, HashSet <IState> >());
            }

            foreach (IState state in allStates)
            {
                foreach (var transition in dfa.Transitions(state))
                {
                    var symbol   = transition.Key;
                    var newState = transition.Value;
                    if (!reverseTransitions[newState].ContainsKey(symbol))
                    {
                        reverseTransitions[newState].Add(symbol, new HashSet <IState>());
                    }

                    reverseTransitions[transition.Value][transition.Key].Add(state);
                }
            }

            return(reverseTransitions);
        }
Пример #25
0
 private static bool IsAccepting(IDfa <Optional <Rule <TLabel> >, TLabel> dfa, IState state)
 {
     return(!dfa.Label(state).IsNone());
 }
Пример #26
0
        private static IReadOnlyCollection <ParseAction <TLabel> > GetAllParseActions(
            CompiledGrammar <TLabel> grammar,
            IState state,
            IDfa <Optional <Rule <TLabel> >, TLabel> dfa,
            TLabel label,
            IReadOnlyDictionary <TLabel, IReadOnlyCollection <DfaAndState <TLabel> > > follow,
            IReadOnlyDictionary <TLabel, IReadOnlyCollection <DfaAndState <TLabel> > > firstPlus)
        {
            var actions = new List <ParseAction <TLabel> >();

            var stateLabel  = dfa.Label(state);
            var dfaAndState = new DfaAndState <TLabel>()
            {
                Dfa = dfa, State = state
            };

            if (stateLabel.IsSome() && follow.ContainsKey(label) && follow[label].Contains(dfaAndState))
            {
                actions.Add(
                    new ParseAction <TLabel>()
                {
                    Kind = ParseAction <TLabel> .ActionKind.Reduce, Label = stateLabel.Get().Lhs
                });
            }

            var transitions = dfa.Transitions(state);

            if (transitions.ContainsKey(label))
            {
                var nextState = transitions[label];
                if (!dfa.IsStable(nextState) || dfa.Label(nextState).IsSome())
                {
                    actions.Add(
                        new ParseAction <TLabel>()
                    {
                        Kind = ParseAction <TLabel> .ActionKind.Shift, Label = label
                    });
                }
            }

            if (firstPlus.ContainsKey(label))
            {
                var firstPlusStates = firstPlus[label];
                foreach (var transitionLabel in transitions.Keys)
                {
                    var nextState = transitions[transitionLabel];
                    if ((!dfa.IsStable(nextState) || dfa.Label(nextState).IsSome()) && grammar.Rules.ContainsKey(transitionLabel))
                    {
                        var subDfa = grammar.Rules[transitionLabel];
                        var subDfaAndStartState = new DfaAndState <TLabel>()
                        {
                            Dfa = subDfa, State = subDfa.StartingState()
                        };

                        if (firstPlusStates.Contains(subDfaAndStartState))
                        {
                            actions.Add(
                                new ParseAction <TLabel>()
                            {
                                Kind = ParseAction <TLabel> .ActionKind.Call, Label = transitionLabel
                            });
                        }
                    }
                }
            }

            return(actions);
        }
Пример #27
0
 internal static void CheckDfaStates(IDfa <TSymbol> dfa)
 {
     new DfaStatesConcpetCheck <TSymbol>().Check(dfa.Start);
 }