예제 #1
0
파일: DfaUtils.cs 프로젝트: nobikik9/kju
        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
        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);
        }
예제 #3
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> >());
 }
예제 #4
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");
            }
        }
예제 #5
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));
        }
예제 #6
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);
        }
예제 #7
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);
        }
예제 #8
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");
     }
 }
예제 #9
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);
        }
예제 #10
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);
                    }
                }
            }
        }
예제 #11
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);
        }
예제 #12
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);
        }