Exemplo n.º 1
0
        /*
         * Make a DFA-ish automaton from the NFA-like structure of the regex
         */
        public TokenAutomaton ConstructAutomaton()
        {
            Dictionary<ISet<Node>, TokenAutomaton.Node> DFAStates =
                new Dictionary<ISet<Node>, TokenAutomaton.Node>(new SetEqualityComparer<Node>());
            TokenAutomaton.Node DFAStartState = new TokenAutomaton.Node();
            // set of nodes accessible from NFA start state
            ISet<Node> NFAStartStates = start.EpsilonMove();
            DFAStates.Add(NFAStartStates, DFAStartState);

            Stack<ISet<Node>> s = new Stack<ISet<Node>>();
            s.Push(NFAStartStates);

            while (s.Count != 0)
            {
                // pop a NFA state
                ISet<Node> currentNFAStates = s.Pop();
                // get the corresponding DFA state
                TokenAutomaton.Node currentDFAState = DFAStates[currentNFAStates];
                ISet<char> nextChars = new HashSet<char>();

                // find which characters we can move with from currentNFAStates
                foreach (Node n in currentNFAStates)
                    nextChars.UnionWith(n.transitions.Keys);

                foreach (char c in nextChars)
                {
                    // set of NFA states that can be reached from the current set with input c
                    ISet<Node> nextNFAStates = Node.Move(currentNFAStates, c);
                    if (nextNFAStates.Count != 0)
                    {
                        // include NFA states that can be reached with an epsilon transition
                        HashSet<Node> epsilonClosure = new HashSet<Node>();
                        epsilonClosure.UnionWith(nextNFAStates);
                        epsilonClosure.UnionWith(Node.EpsilonMove(nextNFAStates));

                        TokenAutomaton.Node nextDFAState;
                        if (!DFAStates.TryGetValue(epsilonClosure, out nextDFAState))
                        {
                            // no DFA state exists for this set of NFA states yet, so we create one
                            nextDFAState = new TokenAutomaton.Node();

                            // set accepted token types for the DFA state
                            foreach (Node n in epsilonClosure)
                            {
                                if (n.tokenType != null &&
                                    (nextDFAState.acceptedTokenType == null ||
                                    (n.tokenType.TokenPriority == TokenType.Priority.Keyword)))
                                {
                                    nextDFAState.acceptedTokenType = n.tokenType;
                                }
                            }

                            DFAStates.Add(epsilonClosure, nextDFAState);
                            s.Push(epsilonClosure);
                        }

                        // create transition
                        currentDFAState.transitions.Add(c, nextDFAState);
                    }
                }
            }

            return new TokenAutomaton(DFAStartState);
        }
Exemplo n.º 2
0
        /*
         * Make a DFA-ish automaton from the NFA-like structure of the regex
         */
        public TokenAutomaton ConstructAutomaton()
        {
            Dictionary <ISet <Node>, TokenAutomaton.Node> DFAStates =
                new Dictionary <ISet <Node>, TokenAutomaton.Node>(new SetEqualityComparer <Node>());

            TokenAutomaton.Node DFAStartState = new TokenAutomaton.Node();
            // set of nodes accessible from NFA start state
            ISet <Node> NFAStartStates = start.EpsilonMove();

            DFAStates.Add(NFAStartStates, DFAStartState);

            Stack <ISet <Node> > s = new Stack <ISet <Node> >();

            s.Push(NFAStartStates);

            while (s.Count != 0)
            {
                // pop a NFA state
                ISet <Node> currentNFAStates = s.Pop();
                // get the corresponding DFA state
                TokenAutomaton.Node currentDFAState = DFAStates[currentNFAStates];
                ISet <char>         nextChars       = new HashSet <char>();

                // find which characters we can move with from currentNFAStates
                foreach (Node n in currentNFAStates)
                {
                    nextChars.UnionWith(n.transitions.Keys);
                }


                foreach (char c in nextChars)
                {
                    // set of NFA states that can be reached from the current set with input c
                    ISet <Node> nextNFAStates = Node.Move(currentNFAStates, c);
                    if (nextNFAStates.Count != 0)
                    {
                        // include NFA states that can be reached with an epsilon transition
                        HashSet <Node> epsilonClosure = new HashSet <Node>();
                        epsilonClosure.UnionWith(nextNFAStates);
                        epsilonClosure.UnionWith(Node.EpsilonMove(nextNFAStates));

                        TokenAutomaton.Node nextDFAState;
                        if (!DFAStates.TryGetValue(epsilonClosure, out nextDFAState))
                        {
                            // no DFA state exists for this set of NFA states yet, so we create one
                            nextDFAState = new TokenAutomaton.Node();

                            // set accepted token types for the DFA state
                            foreach (Node n in epsilonClosure)
                            {
                                if (n.tokenType != null &&
                                    (nextDFAState.acceptedTokenType == null ||
                                     (n.tokenType.TokenPriority == TokenType.Priority.Keyword)))
                                {
                                    nextDFAState.acceptedTokenType = n.tokenType;
                                }
                            }

                            DFAStates.Add(epsilonClosure, nextDFAState);
                            s.Push(epsilonClosure);
                        }

                        // create transition
                        currentDFAState.transitions.Add(c, nextDFAState);
                    }
                }
            }

            return(new TokenAutomaton(DFAStartState));
        }