예제 #1
0
        public virtual void ReportRecursionOverflow(DFAState d,
                                                    NFAConfiguration recursionNFAConfiguration)
        {
            // track the state number rather than the state as d will change
            // out from underneath us; hash wouldn't return any value

            // left-recursion is detected in start state.  Since we can't
            // call resolveNondeterminism() on the start state (it would
            // not look k=1 to get min single token lookahead), we must
            // prevent errors derived from this state.  Avoid start state
            if (d.stateNumber > 0)
            {
                int stateI = d.stateNumber;
                _stateToRecursionOverflowConfigurationsMap.Map(stateI, recursionNFAConfiguration);
            }
        }
        protected internal virtual IParseTree MatchImpl(IParseTree tree, IParseTree patternTree, MultiMap<string, IParseTree> labels)
        {
            if (tree == null)
            {
                throw new ArgumentException("tree cannot be null");
            }
            if (patternTree == null)
            {
                throw new ArgumentException("patternTree cannot be null");
            }
            // x and <ID>, x and y, or x and x; or could be mismatched types
            if (tree is ITerminalNode && patternTree is ITerminalNode)
            {
                ITerminalNode t1 = (ITerminalNode)tree;
                ITerminalNode t2 = (ITerminalNode)patternTree;
                IParseTree mismatchedNode = null;
                // both are tokens and they have same type
                if (t1.Symbol.Type == t2.Symbol.Type)
                {
                    if (t2.Symbol is TokenTagToken)
                    {
                        // x and <ID>
                        TokenTagToken tokenTagToken = (TokenTagToken)t2.Symbol;
                        // track label->list-of-nodes for both token name and label (if any)

                        labels.Map(tokenTagToken.TokenName, tree);
                        if (tokenTagToken.Label != null)
                        {
                            labels.Map(tokenTagToken.Label, tree);
                        }
                    }
                    else
                    {
                        if (t1.GetText().Equals(t2.GetText(), StringComparison.Ordinal))
                        {
                        }
                        else
                        {
                            // x and x
                            // x and y
                            if (mismatchedNode == null)
                            {
                                mismatchedNode = t1;
                            }
                        }
                    }
                }
                else
                {
                    if (mismatchedNode == null)
                    {
                        mismatchedNode = t1;
                    }
                }
                return mismatchedNode;
            }
            if (tree is ParserRuleContext && patternTree is ParserRuleContext)
            {
                ParserRuleContext r1 = (ParserRuleContext)tree;
                ParserRuleContext r2 = (ParserRuleContext)patternTree;
                IParseTree mismatchedNode = null;
                // (expr ...) and <expr>
                RuleTagToken ruleTagToken = GetRuleTagToken(r2);
                if (ruleTagToken != null)
                {
                    if (r1.RuleIndex == r2.RuleIndex)
                    {
                        // track label->list-of-nodes for both rule name and label (if any)
                        labels.Map(ruleTagToken.RuleName, tree);
                        if (ruleTagToken.Label != null)
                        {
                            labels.Map(ruleTagToken.Label, tree);
                        }
                    }
                    else
                    {
                        if (mismatchedNode == null)
                        {
                            mismatchedNode = r1;
                        }
                    }
                    return mismatchedNode;
                }
                // (expr ...) and (expr ...)
                if (r1.ChildCount != r2.ChildCount)
                {
                    if (mismatchedNode == null)
                    {
                        mismatchedNode = r1;
                    }
                    return mismatchedNode;
                }
                int n = r1.ChildCount;
                for (int i = 0; i < n; i++)
                {
                    IParseTree childMatch = MatchImpl(r1.GetChild(i), patternTree.GetChild(i), labels);
                    if (childMatch != null)
                    {
                        return childMatch;
                    }
                }
                return mismatchedNode;
            }
            // if nodes aren't both tokens or both rule nodes, can't match
            return tree;
        }
예제 #3
0
 public void edge(String source, String target)
 {
     edges.Map(source, target);
 }
예제 #4
0
        protected internal virtual IParseTree MatchImpl(IParseTree tree, IParseTree patternTree, MultiMap <string, IParseTree> labels)
        {
            if (tree == null)
            {
                throw new ArgumentException("tree cannot be null");
            }
            if (patternTree == null)
            {
                throw new ArgumentException("patternTree cannot be null");
            }
            // x and <ID>, x and y, or x and x; or could be mismatched types
            if (tree is ITerminalNode && patternTree is ITerminalNode)
            {
                ITerminalNode t1             = (ITerminalNode)tree;
                ITerminalNode t2             = (ITerminalNode)patternTree;
                IParseTree    mismatchedNode = null;
                // both are tokens and they have same type
                if (t1.Symbol.Type == t2.Symbol.Type)
                {
                    if (t2.Symbol is TokenTagToken)
                    {
                        // x and <ID>
                        TokenTagToken tokenTagToken = (TokenTagToken)t2.Symbol;
                        // track label->list-of-nodes for both token name and label (if any)

                        labels.Map(tokenTagToken.TokenName, tree);
                        if (tokenTagToken.Label != null)
                        {
                            labels.Map(tokenTagToken.Label, tree);
                        }
                    }
                    else
                    {
                        if (t1.GetText().Equals(t2.GetText(), StringComparison.Ordinal))
                        {
                        }
                        else
                        {
                            // x and x
                            // x and y
                            if (mismatchedNode == null)
                            {
                                mismatchedNode = t1;
                            }
                        }
                    }
                }
                else
                {
                    if (mismatchedNode == null)
                    {
                        mismatchedNode = t1;
                    }
                }
                return(mismatchedNode);
            }
            if (tree is ParserRuleContext && patternTree is ParserRuleContext)
            {
                ParserRuleContext r1             = (ParserRuleContext)tree;
                ParserRuleContext r2             = (ParserRuleContext)patternTree;
                IParseTree        mismatchedNode = null;
                // (expr ...) and <expr>
                RuleTagToken ruleTagToken = GetRuleTagToken(r2);
                if (ruleTagToken != null)
                {
                    if (r1.RuleIndex == r2.RuleIndex)
                    {
                        // track label->list-of-nodes for both rule name and label (if any)
                        labels.Map(ruleTagToken.RuleName, tree);
                        if (ruleTagToken.Label != null)
                        {
                            labels.Map(ruleTagToken.Label, tree);
                        }
                    }
                    else
                    {
                        if (mismatchedNode == null)
                        {
                            mismatchedNode = r1;
                        }
                    }
                    return(mismatchedNode);
                }
                // (expr ...) and (expr ...)
                if (r1.ChildCount != r2.ChildCount)
                {
                    if (mismatchedNode == null)
                    {
                        mismatchedNode = r1;
                    }
                    return(mismatchedNode);
                }
                int n = r1.ChildCount;
                for (int i = 0; i < n; i++)
                {
                    IParseTree childMatch = MatchImpl(r1.GetChild(i), patternTree.GetChild(i), labels);
                    if (childMatch != null)
                    {
                        return(childMatch);
                    }
                }
                return(mismatchedNode);
            }
            // if nodes aren't both tokens or both rule nodes, can't match
            return(tree);
        }
예제 #5
0
파일: DFAState.cs 프로젝트: zapov/antlrcs
        /** Walk each NFA configuration in this DFA state looking for a conflict
         *  where (s|i|ctx) and (s|j|ctx) exist, indicating that state s with
         *  context conflicting ctx predicts alts i and j.  Return an Integer set
         *  of the alternative numbers that conflict.  Two contexts conflict if
         *  they are equal or one is a stack suffix of the other or one is
         *  the empty context.
         *
         *  Use a hash table to record the lists of configs for each state
         *  as they are encountered.  We need only consider states for which
         *  there is more than one configuration.  The configurations' predicted
         *  alt must be different or must have different contexts to avoid a
         *  conflict.
         *
         *  Don't report conflicts for DFA states that have conflicting Tokens
         *  rule NFA states; they will be resolved in favor of the first rule.
         */
        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);
        }
예제 #6
0
파일: DFAState.cs 프로젝트: bszafko/antlrcs
        /** Walk each NFA configuration in this DFA state looking for a conflict
         *  where (s|i|ctx) and (s|j|ctx) exist, indicating that state s with
         *  context conflicting ctx predicts alts i and j.  Return an Integer set
         *  of the alternative numbers that conflict.  Two contexts conflict if
         *  they are equal or one is a stack suffix of the other or one is
         *  the empty context.
         *
         *  Use a hash table to record the lists of configs for each state
         *  as they are encountered.  We need only consider states for which
         *  there is more than one configuration.  The configurations' predicted
         *  alt must be different or must have different contexts to avoid a
         *  conflict.
         *
         *  Don't report conflicts for DFA states that have conflicting Tokens
         *  rule NFA states; they will be resolved in favor of the first rule.
         */
        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.Size();
            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.Get( 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;
                var configsForState = stateToConfigListMap.get( stateI );
                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 )
            {
                var configsForState = stateToConfigListMap.get( stateI );
                // 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;
        }
예제 #7
0
        public virtual DFA CreateLL_1_LookaheadDFA( int decision )
        {
            Decision d = GetDecision( decision );
            string enclosingRule = d.startState.enclosingRule.Name;
            Rule r = d.startState.enclosingRule;
            NFAState decisionStartState = GetDecisionNFAStartState( decision );

            if ( composite.WatchNFAConversion )
            {
                Console.Out.WriteLine( "--------------------\nattempting LL(1) DFA (d="
                                   + decisionStartState.DecisionNumber + ") for " +
                                   decisionStartState.Description );
            }

            if ( r.IsSynPred && !synPredNamesUsedInDFA.Contains( enclosingRule ) )
            {
                return null;
            }

            // compute lookahead for each alt
            int numAlts = GetNumberOfAltsForDecisionNFA( decisionStartState );
            LookaheadSet[] altLook = new LookaheadSet[numAlts + 1];
            for ( int alt = 1; alt <= numAlts; alt++ )
            {
                int walkAlt =
                    decisionStartState.TranslateDisplayAltToWalkAlt( alt );
                NFAState altLeftEdge = GetNFAStateForAltOfDecision( decisionStartState, walkAlt );
                NFAState altStartState = (NFAState)altLeftEdge.transition[0].Target;
                //[email protected]("alt "+alt+" start state = "+altStartState.stateNumber);
                altLook[alt] = ll1Analyzer.Look( altStartState );
                //[email protected]("alt "+alt+": "+altLook[alt].toString(this));
            }

            // compare alt i with alt j for disjointness
            bool decisionIsLL_1 = true;
            for ( int i = 1; i <= numAlts; i++ )
            {
                for ( int j = i + 1; j <= numAlts; j++ )
                {
                    /*
                    [email protected]("compare "+i+", "+j+": "+
                                       altLook[i].toString(this)+" with "+
                                       altLook[j].toString(this));
                    */
                    LookaheadSet collision = altLook[i].Intersection( altLook[j] );
                    if ( !collision.IsNil )
                    {
                        //[email protected]("collision (non-LL(1)): "+collision.toString(this));
                        decisionIsLL_1 = false;
                        goto outer;
                    }
                }
            }

            outer:
            bool foundConfoundingPredicate =
                ll1Analyzer.DetectConfoundingPredicates( decisionStartState );
            if ( decisionIsLL_1 && !foundConfoundingPredicate )
            {
                // build an LL(1) optimized DFA with edge for each altLook[i]
                if ( NFAToDFAConverter.debug )
                {
                    Console.Out.WriteLine( "decision " + decision + " is simple LL(1)" );
                }
                DFA lookaheadDFA2 = new LL1DFA( decision, decisionStartState, altLook );
                SetLookaheadDFA( decision, lookaheadDFA2 );
                UpdateLineColumnToLookaheadDFAMap( lookaheadDFA2 );
                return lookaheadDFA2;
            }

            // not LL(1) but perhaps we can solve with simplified predicate search
            // even if k=1 set manually, only resolve here if we have preds; i.e.,
            // don't resolve etc...

            /*
            SemanticContext visiblePredicates =
                ll1Analyzer.getPredicates(decisionStartState);
            boolean foundConfoundingPredicate =
                ll1Analyzer.detectConfoundingPredicates(decisionStartState);
                */

            // exit if not forced k=1 or we found a predicate situation we
            // can't handle: predicates in rules invoked from this decision.
            if ( GetUserMaxLookahead( decision ) != 1 || // not manually set to k=1
                 !GetAutoBacktrackMode( decision ) ||
                 foundConfoundingPredicate )
            {
                //[email protected]("trying LL(*)");
                return null;
            }

            IList<IIntSet> edges = new List<IIntSet>();
            for ( int i = 1; i < altLook.Length; i++ )
            {
                LookaheadSet s = altLook[i];
                edges.Add( (IntervalSet)s.TokenTypeSet );
            }
            IList<IIntSet> disjoint = MakeEdgeSetsDisjoint( edges );
            //[email protected]("disjoint="+disjoint);

            MultiMap<IntervalSet, int> edgeMap = new MultiMap<IntervalSet, int>();
            for ( int i = 0; i < disjoint.Count; i++ )
            {
                IntervalSet ds = (IntervalSet)disjoint[i];
                for ( int alt = 1; alt < altLook.Length; alt++ )
                {
                    LookaheadSet look = altLook[alt];
                    if ( !ds.And( look.TokenTypeSet ).IsNil )
                    {
                        edgeMap.Map( ds, alt );
                    }
                }
            }
            //[email protected]("edge map: "+edgeMap);

            // TODO: how do we know we covered stuff?

            // build an LL(1) optimized DFA with edge for each altLook[i]
            DFA lookaheadDFA = new LL1DFA( decision, decisionStartState, edgeMap );
            SetLookaheadDFA( decision, lookaheadDFA );

            // create map from line:col to decision DFA (for ANTLRWorks)
            UpdateLineColumnToLookaheadDFAMap( lookaheadDFA );

            return lookaheadDFA;
        }