public void PushBack(State state)
 {
     _states.PushBack(state);
 }
 public void PushFront(State state)
 {
     _states.PushFront(state);
 }
 public PatternState()
 {
     _state = null;
     _startIndex = -1;
 }
 public PatternState(PatternState other)
 {
     _state = other.State;
     _startIndex = other.StateIndex;
 }
 public void AddTransition(char input, State destination)
 {
     if (!_destinations.ContainsKey(input))
         _destinations[input] = new List<State>();
     _destinations[input].Add(destination);
 }
        //A|B
        private bool Union()
        {
            if (_operandStack.Count < 2)
                return false;
            FiniteStateAutomaton B = Pop();
            FiniteStateAutomaton A = Pop();

            var startState = new State(++_nextStateId);
            var endState = new State(++_nextStateId);
            startState.AddTransition(EPSILON, A.GetFirstState());
            startState.AddTransition(EPSILON, B.GetFirstState());

            A.GetLastState().AddTransition(EPSILON, endState);
            B.GetLastState().AddTransition(EPSILON, endState);

            A.PushFront(startState);
            foreach (var item in B.GetStates())
            {
                A.PushBack(item);
            }
            A.PushBack(endState);

            _operandStack.Push(A);
            return true;
        }
        //Kleen A*
        //
        private bool Star()
        {
            if (_operandStack.Count < 1)
                return false;
            FiniteStateAutomaton A = Pop();
            var startState = new State(++_nextStateId);
            var endState = new State(++_nextStateId);
            startState.AddTransition(EPSILON, endState);
            startState.AddTransition(EPSILON, A.GetFirstState());

            A.GetLastState().AddTransition(EPSILON, endState);
            A.GetLastState().AddTransition(EPSILON, A.GetFirstState());
            A.PushBack(endState);
            A.PushFront(startState);

            _operandStack.Push(A);
            return true;
        }
        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);
        }
        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);
                    }
                }
            }
        }