예제 #1
0
        private void CreateNFA(string input)
        {
            Stack<char> operatorStack = new Stack<char>();
            var expandedInput = ConcatExpand(input);
            for (int i = 0; i < expandedInput.Length; i++)
            {
                char c = expandedInput[i];
                if (char.IsLetterOrDigit(c))
                    Push(c);
                else if (operatorStack.Count == 0)
                    operatorStack.Push(c);
                else if (c == '(')
                    operatorStack.Push(c);
                else if (c == ')')
                {
                    while (operatorStack.Peek() != '(')
                    {
                        var op = operatorStack.Pop();
                        if (op == (char)8)
                            Concat();
                        else if (op == '*')
                            Star();
                        else if (op == '|')
                            Union();
                        else
                            return;
                    }
                    operatorStack.Pop(); //pop up '('
                }
                else
                {
                    while (operatorStack.Count != 0 && Presedece(c, operatorStack.Peek()))
                    {
                        var op = operatorStack.Pop();
                        if (op == (char)8)
                            Concat();
                        else if (op == '*')
                            Star();
                        else if (op == '|')
                            Union();
                        else
                            return;
                    }
                    operatorStack.Push(c);
                }
            }

            while (operatorStack.Count > 0)
            {
                var op = operatorStack.Pop();
                if (op == (char)8)
                    Concat();
                else if (op == '*')
                    Star();
                else if (op == '|')
                    Union();
                else
                    return;
            }

            if (_operandStack.Count == 0)
                return;
            var A = _operandStack.Pop();
            A.GetLastState().AcceptState = true;

            #if DEBUG
            if (A.GetFirstState() != null)
            {
                using (var stream = File.OpenWrite("NFA.txt"))
                {
                    using (var sw = new StreamWriter(stream))
                    {
                        HashSet<int> processedStates = new HashSet<int>();
                        Deque<State> unprocessedStates = new Deque<State>();
                        unprocessedStates.PushBack(A.GetFirstState());

                        while(unprocessedStates.Count>0)
                        {
                            var state = unprocessedStates.PopFront();
                            var labels = state.GetLabels();
                            foreach (var label in labels)
                            {
                                var destinationStates = state.GetStates(label);
                                if (destinationStates != null)
                                {
                                    foreach (var dest in destinationStates)
                                    {
                                        sw.WriteLine("Start:" + state.ToString() + "," + "End:" + dest.ToString() + "," + "Label:" + (label!=EPSILON? label.ToString():"EPSILON"));
                                        if (!processedStates.Contains(dest.StateId))
                                        {
                                            unprocessedStates.PushBack(dest);
                                        }
                                    }
                                }
                            }
                            processedStates.Add(state.StateId);
                        }
                    }
                }
            }

            #endif
            _NFA = A;
        }
예제 #2
0
        private void Push(Char input)
        {
            var state0 = new State(++_nextStateId);
            var state1 = new State(++_nextStateId);
            state0.AddTransition(input, state1);

            FiniteStateAutomaton fsa = new FiniteStateAutomaton();
            fsa.PushBack(state0);
            fsa.PushBack(state1);

            _operandStack.Push(fsa);

            _inputSet.Add(input);
        }
예제 #3
0
        private void ConvertNFAToDFA()
        {
            if (_NFA == null)
                return;

            if (_DFA == null)
                _DFA = new FiniteStateAutomaton();
            _nextStateId = 0;
            Stack<State> unmarkedStates = new Stack<State>();
            HashSet<State> DFAStartStateSet = new HashSet<State>();
            HashSet<State> NFAStartStateSet = new HashSet<State>();

            NFAStartStateSet.Add(_NFA.GetFirstState());
            DFAStartStateSet = EpsilonClosure(NFAStartStateSet);

            var DFAStartState = new State(++_nextStateId, DFAStartStateSet);
            _DFA.PushBack(DFAStartState);
            unmarkedStates.Push(DFAStartState);
            while (unmarkedStates.Count > 0)
            {
                var processingDFAState = unmarkedStates.Pop();
                State dest = null;
                foreach (var item in _inputSet)
                {
                    var moveStates = Move(item, processingDFAState.NFAStatesSet);
                    var epsilonClosureStats = EpsilonClosure(moveStates);

                    bool found = false;
                    foreach (var s in _DFA.GetStates())
                    {
                        if (SameStatesSet(s.NFAStatesSet, epsilonClosureStats))
                        {
                            found = true;
                            dest = s;
                            break;
                        }
                    }

                    if (!found)
                    {
                        var newState = new State(++_nextStateId, epsilonClosureStats);
                        unmarkedStates.Push(newState);
                        _DFA.PushBack(newState);
                        processingDFAState.AddTransition(item, newState);
                    }
                    else
                    {
                        processingDFAState.AddTransition(item, dest);
                    }
                }
            }
        }