Antlr3.Analysis.DFAState.GetConflictingAlts C# (CSharp) Method

GetConflictingAlts() protected method

protected GetConflictingAlts ( ) : HashSet
return HashSet
        protected virtual HashSet<int> GetConflictingAlts()
        {
            // TODO this is called multiple times: cache result?
            //[email protected]("getNondetAlts for DFA state "+stateNumber);
            HashSet<int> nondeterministicAlts = new HashSet<int>();

            // If only 1 NFA conf then no way it can be nondeterministic;
            // save the overhead.  There are many o-a->o NFA transitions
            // and so we save a hash map and iterator creation for each
            // state.
            int numConfigs = _nfaConfigurations.Count;
            if ( numConfigs <= 1 )
            {
                return null;
            }

            // First get a list of configurations for each state.
            // Most of the time, each state will have one associated configuration.
            MultiMap<int, NFAConfiguration> stateToConfigListMap =
                new MultiMap<int, NFAConfiguration>();
            for ( int i = 0; i < numConfigs; i++ )
            {
                NFAConfiguration configuration = (NFAConfiguration)_nfaConfigurations[i];
                int stateI = configuration.State;
                stateToConfigListMap.Map( stateI, configuration );
            }
            // potential conflicts are states with > 1 configuration and diff alts
            ICollection<int> states = stateToConfigListMap.Keys.ToArray();
            int numPotentialConflicts = 0;
            foreach ( int stateI in states )
            {
                bool thisStateHasPotentialProblem = false;
                IList<NFAConfiguration> configsForState;
                stateToConfigListMap.TryGetValue(stateI, out configsForState);
                int alt = 0;
                int numConfigsForState = configsForState.Count;
                for ( int i = 0; i < numConfigsForState && numConfigsForState > 1; i++ )
                {
                    NFAConfiguration c = (NFAConfiguration)configsForState[i];
                    if ( alt == 0 )
                    {
                        alt = c.Alt;
                    }
                    else if ( c.Alt != alt )
                    {
                        /*
                        [email protected]("potential conflict in state "+stateI+
                                           " configs: "+configsForState);
                        */
                        // 11/28/2005: don't report closures that pinch back
                        // together in Tokens rule.  We want to silently resolve
                        // to the first token definition ala lex/flex by ignoring
                        // these conflicts.
                        // Also this ensures that lexers look for more and more
                        // characters (longest match) before resorting to predicates.
                        // TestSemanticPredicates.testLexerMatchesLongestThenTestPred()
                        // for example would terminate at state s1 and test predicate
                        // meaning input "ab" would test preds to decide what to
                        // do but it should match rule C w/o testing preds.
                        if ( dfa.Nfa.Grammar.type != GrammarType.Lexer ||
                             !dfa.NFADecisionStartState.enclosingRule.Name.Equals( Grammar.ArtificialTokensRuleName ) )
                        {
                            numPotentialConflicts++;
                            thisStateHasPotentialProblem = true;
                        }
                    }
                }
                if ( !thisStateHasPotentialProblem )
                {
                    // remove NFA state's configurations from
                    // further checking; no issues with it
                    // (can't remove as it's concurrent modification; set to null)
                    stateToConfigListMap[stateI] = null;
                }
            }

            // a fast check for potential issues; most states have none
            if ( numPotentialConflicts == 0 )
            {
                return null;
            }

            // we have a potential problem, so now go through config lists again
            // looking for different alts (only states with potential issues
            // are left in the states set).  Now we will check context.
            // For example, the list of configs for NFA state 3 in some DFA
            // state might be:
            //   [3|2|[28 18 $], 3|1|[28 $], 3|1, 3|2]
            // I want to create a map from context to alts looking for overlap:
            //   [28 18 $] -> 2
            //   [28 $] -> 1
            //   [$] -> 1,2
            // Indeed a conflict exists as same state 3, same context [$], predicts
            // alts 1 and 2.
            // walk each state with potential conflicting configurations
            foreach ( int stateI in states )
            {
                IList<NFAConfiguration> configsForState;
                stateToConfigListMap.TryGetValue(stateI, out configsForState);
                // compare each configuration pair s, t to ensure:
                // s.ctx different than t.ctx if s.alt != t.alt
                int numConfigsForState = 0;
                if ( configsForState != null )
                {
                    numConfigsForState = configsForState.Count;
                }
                for ( int i = 0; i < numConfigsForState; i++ )
                {
                    NFAConfiguration s = configsForState[i];
                    for ( int j = i + 1; j < numConfigsForState; j++ )
                    {
                        NFAConfiguration t = configsForState[j];
                        // conflicts means s.ctx==t.ctx or s.ctx is a stack
                        // suffix of t.ctx or vice versa (if alts differ).
                        // Also a conflict if s.ctx or t.ctx is empty
                        if ( s.Alt != t.Alt && s.Context.ConflictsWith( t.Context ) )
                        {
                            nondeterministicAlts.Add( s.Alt );
                            nondeterministicAlts.Add( t.Alt );
                        }
                    }
                }
            }

            if ( nondeterministicAlts.Count == 0 )
            {
                return null;
            }
            return nondeterministicAlts;
        }