Esempio n. 1
0
        public static Automaton RemoveEpsilon(Automaton source)
        {
            //标记所有输入的边都没有消耗字符的状态
            var nfa = new Automaton();

            nfa.CaptureNames = source.CaptureNames;
            var newStartstate = nfa.AddState();

            nfa.StartState = newStartstate;
            List <Transition> transitions = new List <Transition>();
            var oldToNew = new Dictionary <State, State>
            {
                [source.StartState] = newStartstate
            };
            var newToOld = new Dictionary <State, State>()
            {
                [newStartstate] = source.StartState
            };
            var epsilonStates = new List <State>();

            for (int i = 0; i < nfa.States.Count; ++i)
            {
                var state    = nfa.States[i];
                var oldState = newToOld[state];
                FindPath(oldState, state, transitions, epsilonStates);
                if (oldState.IsFinalState)
                {
                    state.IsFinalState = true;
                }
                foreach (var trans in transitions)
                {
                    var target = trans.End;
                    if (!oldToNew.Keys.Contains(target))
                    {
                        var newState = nfa.AddState();
                        oldToNew.Add(target, newState);
                        newToOld.Add(newState, target);
                    }
                    var newTransition = nfa.AddTransition(state, oldToNew[target], trans.TransitionType);
                    newTransition.Range   = trans.Range;
                    newTransition.Capture = trans.Capture;
                    newTransition.Index   = trans.Index;
                }
                transitions.Clear();
                epsilonStates.Clear();
            }
            return(nfa);
        }
Esempio n. 2
0
        public static Automaton NfaToDfa(Automaton nfa, out MultiValueDictionary <State, State> dfaStatesToNfa)
        {
            var dfa = new Automaton();

            dfa.CaptureNames = nfa.CaptureNames;
            var dfaStartState = dfa.AddState();

            dfa.StartState = dfaStartState;
            var nfaTransitionsToDfa = new MultiValueDictionary <Transition, Transition>();
            var transitionClasses   = new List <Transition>();
            var mergeStates         = new HashSet <State>();

            dfaStatesToNfa = new MultiValueDictionary <State, State>();
            dfaStatesToNfa.Add(dfaStartState, nfa.StartState);
            //不动点算法,不能使用 foreach!
            for (int i = 0; i < dfa.States.Count; ++i)
            {
                var curDfaState = dfa.States[i];
                var nfaStates   = dfaStatesToNfa[curDfaState];
                foreach (var nfaState in nfaStates)
                {
                    foreach (var outTransition in nfaState.Output)
                    {
                        if (!nfaTransitionsToDfa.Values.SelectMany(transitions => transitions).Contains(outTransition))
                        {
                            transitionClasses.Add(outTransition);
                            nfaTransitionsToDfa.Add(outTransition, outTransition);
                        }
                    }
                }

                foreach (var transitionClass in transitionClasses)
                {
                    var nfaTransitions = nfaTransitionsToDfa[transitionClass];
                    foreach (var nfaTransition in nfaTransitions)
                    {
                        var state = nfaTransition.End;
                        if (!mergeStates.Contains(state))
                        {
                            mergeStates.Add(state);
                        }
                    }

                    mergeStates.OrderBy(state => state);

                    //mergeStates 是候选的一个 DFA 状态。在这之前,还需要判断:这个候选状态是否已经存在于 DFA 中了?
                    //var isContained = dfaStatesToNfa.Values.Contains((IReadOnlyCollection<State>)mergeStates);
                    State newDfaState = null;
                    foreach (var dfaState in dfaStatesToNfa.Keys)
                    {
                        var prevNfaStates = dfaStatesToNfa[dfaState];
                        if (prevNfaStates.Count == mergeStates.Count &&
                            prevNfaStates.SequenceEqual(mergeStates))
                        {
                            newDfaState = dfaState;
                            break;
                        }
                    }
                    if (newDfaState == null)
                    {
                        newDfaState = dfa.AddState();
                        dfaStatesToNfa.AddRange(newDfaState, mergeStates);
                        newDfaState.IsFinalState = mergeStates.Any(state => state.IsFinalState);
                    }

                    var dfaTransition = dfa.AddTransition(curDfaState, newDfaState, transitionClass.TransitionType);
                    dfaTransition.Capture = transitionClass.Capture;
                    dfaTransition.Range   = transitionClass.Range;
                    dfaTransition.Index   = transitionClass.Index;
                    mergeStates.Clear();
                }
                transitionClasses.Clear();
                nfaTransitionsToDfa.Clear();
            }

            return(dfa);
        }
Esempio n. 3
0
        public static Automaton NfaToDfa(Automaton nfa, out MultiValueDictionary<State, State> dfaStatesToNfa)
        {
            var dfa = new Automaton();
            dfa.CaptureNames = nfa.CaptureNames;
            var dfaStartState = dfa.AddState();
            dfa.StartState = dfaStartState;
            var nfaTransitionsToDfa = new MultiValueDictionary<Transition, Transition>();
            var transitionClasses = new List<Transition>();
            var mergeStates = new HashSet<State>();
            dfaStatesToNfa = new MultiValueDictionary<State, State>();
            dfaStatesToNfa.Add(dfaStartState, nfa.StartState);
            //不动点算法,不能使用 foreach!
            for(int i = 0; i < dfa.States.Count; ++i)
            {
                var curDfaState = dfa.States[i];
                var nfaStates = dfaStatesToNfa[curDfaState];
                foreach(var nfaState in nfaStates)
                {
                    foreach(var outTransition in nfaState.Output)
                    {
                        if (!nfaTransitionsToDfa.Values.SelectMany(transitions => transitions).Contains(outTransition))
                        {
                            transitionClasses.Add(outTransition);
                            nfaTransitionsToDfa.Add(outTransition, outTransition);
                        }
                    }
                }

                foreach(var transitionClass in transitionClasses)
                {
                    var nfaTransitions = nfaTransitionsToDfa[transitionClass];
                    foreach(var nfaTransition in nfaTransitions)
                    {
                        var state = nfaTransition.End;
                        if (!mergeStates.Contains(state))
                            mergeStates.Add(state);
                    }

                    mergeStates.OrderBy(state => state);

                    //mergeStates 是候选的一个 DFA 状态。在这之前,还需要判断:这个候选状态是否已经存在于 DFA 中了?
                    //var isContained = dfaStatesToNfa.Values.Contains((IReadOnlyCollection<State>)mergeStates);
                    State newDfaState = null;
                    foreach(var dfaState in dfaStatesToNfa.Keys)
                    {
                        var prevNfaStates = dfaStatesToNfa[dfaState];
                        if (prevNfaStates.Count == mergeStates.Count &&
                            prevNfaStates.SequenceEqual(mergeStates))
                        {
                            newDfaState = dfaState;
                            break;
                        }
                    }
                    if(newDfaState == null)
                    {
                        newDfaState = dfa.AddState();
                        dfaStatesToNfa.AddRange(newDfaState, mergeStates);
                        newDfaState.IsFinalState = mergeStates.Any(state => state.IsFinalState);
                    }

                    var dfaTransition = dfa.AddTransition(curDfaState, newDfaState, transitionClass.TransitionType);
                    dfaTransition.Capture = transitionClass.Capture;
                    dfaTransition.Range = transitionClass.Range;
                    dfaTransition.Index = transitionClass.Index;
                    mergeStates.Clear();
                }
                transitionClasses.Clear();
                nfaTransitionsToDfa.Clear();
            }

            return dfa;
        }
Esempio n. 4
0
        public static Automaton RemoveEpsilon(Automaton source)
        {
            //标记所有输入的边都没有消耗字符的状态
            var nfa = new Automaton();
            nfa.CaptureNames = source.CaptureNames;
            var newStartstate = nfa.AddState();
            nfa.StartState = newStartstate;
            List<Transition> transitions = new List<Transition>();
            var oldToNew = new Dictionary<State, State>
            {
                [source.StartState] = newStartstate
            };
            var newToOld = new Dictionary<State, State>()
            {
                [newStartstate] = source.StartState
            };
            var epsilonStates = new List<State>();

            for(int i = 0; i < nfa.States.Count; ++i)
            {
                var state = nfa.States[i];
                var oldState = newToOld[state];
                FindPath(oldState, state, transitions, epsilonStates);
                if (oldState.IsFinalState) state.IsFinalState = true;
                foreach (var trans in transitions)
                {
                    var target = trans.End;
                    if(!oldToNew.Keys.Contains(target))
                    {
                        var newState = nfa.AddState();
                        oldToNew.Add(target, newState);
                        newToOld.Add(newState, target);
                    }
                    var newTransition = nfa.AddTransition(state, oldToNew[target], trans.TransitionType);
                    newTransition.Range = trans.Range;
                    newTransition.Capture = trans.Capture;
                    newTransition.Index = trans.Index;
                }
                transitions.Clear();
                epsilonStates.Clear();
            }
            return nfa;
        }