Ejemplo n.º 1
0
        protected virtual SemanticContext.Predicate GetSynPredForAlt(NFAState decisionStartState,
                                                                     int alt)
        {
            int walkAlt =
                decisionStartState.TranslateDisplayAltToWalkAlt(alt);
            NFAState altLeftEdge =
                nfa.grammar.GetNFAStateForAltOfDecision(decisionStartState, walkAlt);
            NFAState altStartState = (NFAState)altLeftEdge.transition[0].target;

            //[email protected]("alt "+alt+" start state = "+altStartState.stateNumber);
            if (altStartState.transition[0].IsSemanticPredicate)
            {
                SemanticContext ctx = altStartState.transition[0].label.SemanticContext;
                if (ctx.IsSyntacticPredicate)
                {
                    SemanticContext.Predicate p = (SemanticContext.Predicate)ctx;
                    if (p.predicateAST.Type == ANTLRParser.BACKTRACK_SEMPRED)
                    {
                        /*
                         * [email protected]("syn pred for alt "+walkAlt+" "+
                         *                 ((SemanticContext.Predicate)altStartState.transition[0].label.getSemanticContext()).predicateAST);
                         */
                        if (ctx.IsSyntacticPredicate)
                        {
                            nfa.grammar.SynPredUsedInDFA(this, ctx);
                        }
                        return((SemanticContext.Predicate)altStartState.transition[0].label.SemanticContext);
                    }
                }
            }
            return(null);
        }
Ejemplo n.º 2
0
        /** From a set of edgeset->list-of-alts mappings, create a DFA
         *  that uses syn preds for all |list-of-alts|>1.
         */
        public LL1DFA(int decisionNumber,
                      NFAState decisionStartState,
                      MultiMap <IntervalSet, int> edgeMap)
        {
            DFAState s0 = NewState();

            startState                 = s0;
            nfa                        = decisionStartState.nfa;
            NumberOfAlts               = nfa.grammar.GetNumberOfAltsForDecisionNFA(decisionStartState);
            this.decisionNumber        = decisionNumber;
            this.NFADecisionStartState = decisionStartState;
            InitAltRelatedInfo();
            UnreachableAlts = null;
            foreach (var edgeVar in edgeMap)
            {
                IntervalSet edge = edgeVar.Key;
                IList <int> alts = edgeVar.Value;
                alts = alts.OrderBy(i => i).ToList();
                //Collections.sort( alts ); // make sure alts are attempted in order
                //[email protected](edge+" -> "+alts);
                DFAState s = NewState();
                s.LookaheadDepth = 1;
                Label e = GetLabelForSet(edge);
                s0.AddTransition(s, e);
                if (alts.Count == 1)
                {
                    s.acceptState = true;
                    int alt = alts[0];
                    SetAcceptState(alt, s);
                    s.cachedUniquelyPredicatedAlt = alt;
                }
                else
                {
                    // resolve with syntactic predicates.  Add edges from
                    // state s that test predicates.
                    s.IsResolvedWithPredicates = true;
                    for (int i = 0; i < alts.Count; i++)
                    {
                        int alt = (int)alts[i];
                        s.cachedUniquelyPredicatedAlt = NFA.INVALID_ALT_NUMBER;
                        DFAState predDFATarget = GetAcceptState(alt);
                        if (predDFATarget == null)
                        {
                            predDFATarget             = NewState(); // create if not there.
                            predDFATarget.acceptState = true;
                            predDFATarget.cachedUniquelyPredicatedAlt = alt;
                            SetAcceptState(alt, predDFATarget);
                        }
                        // add a transition to pred target from d

                        /*
                         * int walkAlt =
                         *  decisionStartState.translateDisplayAltToWalkAlt(alt);
                         * NFAState altLeftEdge = nfa.grammar.getNFAStateForAltOfDecision(decisionStartState, walkAlt);
                         * NFAState altStartState = (NFAState)altLeftEdge.transition[0].target;
                         * SemanticContext ctx = nfa.grammar.ll1Analyzer.getPredicates(altStartState);
                         * [email protected]("sem ctx = "+ctx);
                         * if ( ctx == null ) {
                         *  ctx = new SemanticContext.TruePredicate();
                         * }
                         * s.addTransition(predDFATarget, new Label(ctx));
                         */
                        SemanticContext.Predicate synpred =
                            GetSynPredForAlt(decisionStartState, alt);
                        if (synpred == null)
                        {
                            synpred = new SemanticContext.TruePredicate();
                        }
                        s.AddTransition(predDFATarget, new PredicateLabel(synpred));
                    }
                }
            }
            //[email protected]("dfa for preds=\n"+this);
        }
Ejemplo n.º 3
0
        protected virtual int DetectConfoundingPredicatesCore(NFAState s,
                                                              Rule enclosingRule,
                                                              bool chaseFollowTransitions)
        {
            //[email protected]("_detectNonAutobacktrackPredicates("+s+")");
            if (!chaseFollowTransitions && s.IsAcceptState)
            {
                if (_grammar.type == GrammarType.Lexer)
                {
                    // FOLLOW makes no sense (at the moment!) for lexical rules.
                    // assume all char can follow
                    return(DETECT_PRED_NOT_FOUND);
                }
                return(DETECT_PRED_EOR);
            }

            if (_lookBusy.Contains(s))
            {
                // return a copy of an empty set; we may modify set inline
                return(DETECT_PRED_NOT_FOUND);
            }
            _lookBusy.Add(s);

            Transition transition0 = s.transition[0];

            if (transition0 == null)
            {
                return(DETECT_PRED_NOT_FOUND);
            }

            if (!(transition0.label.IsSemanticPredicate ||
                  transition0.label.IsEpsilon))
            {
                return(DETECT_PRED_NOT_FOUND);
            }

            if (transition0.label.IsSemanticPredicate)
            {
                //[email protected]("pred "+transition0.label);
                SemanticContext           ctx = transition0.label.SemanticContext;
                SemanticContext.Predicate p   = (SemanticContext.Predicate)ctx;
                if (p.predicateAST.Type != ANTLRParser.BACKTRACK_SEMPRED)
                {
                    return(DETECT_PRED_FOUND);
                }
            }

            /*
             * if ( transition0.label.isSemanticPredicate() ) {
             *  [email protected]("pred "+transition0.label);
             *  SemanticContext ctx = transition0.label.getSemanticContext();
             *  SemanticContext.Predicate p = (SemanticContext.Predicate)ctx;
             *  // if a non-syn-pred found not in enclosingRule, say we found one
             *  if ( p.predicateAST.getType() != ANTLRParser.BACKTRACK_SEMPRED &&
             *       !p.predicateAST.enclosingRuleName.equals(enclosingRule.name) )
             *  {
             *      [email protected]("found pred "+p+" not in "+enclosingRule.name);
             *      return DETECT_PRED_FOUND;
             *  }
             * }
             */

            int result = DetectConfoundingPredicatesCore((NFAState)transition0.target,
                                                         enclosingRule,
                                                         chaseFollowTransitions);

            if (result == DETECT_PRED_FOUND)
            {
                return(DETECT_PRED_FOUND);
            }

            if (result == DETECT_PRED_EOR)
            {
                if (transition0 is RuleClosureTransition)
                {
                    // we called a rule that found the end of the rule.
                    // That means the rule is nullable and we need to
                    // keep looking at what follows the rule ref.  E.g.,
                    // a : b A ; where b is nullable means that LOOK(a)
                    // should include A.
                    RuleClosureTransition ruleInvocationTrans =
                        (RuleClosureTransition)transition0;
                    NFAState following       = (NFAState)ruleInvocationTrans.followState;
                    int      afterRuleResult =
                        DetectConfoundingPredicatesCore(following,
                                                        enclosingRule,
                                                        chaseFollowTransitions);
                    if (afterRuleResult == DETECT_PRED_FOUND)
                    {
                        return(DETECT_PRED_FOUND);
                    }
                }
            }

            Transition transition1 = s.transition[1];

            if (transition1 != null)
            {
                int t1Result =
                    DetectConfoundingPredicatesCore((NFAState)transition1.target,
                                                    enclosingRule,
                                                    chaseFollowTransitions);
                if (t1Result == DETECT_PRED_FOUND)
                {
                    return(DETECT_PRED_FOUND);
                }
            }

            return(DETECT_PRED_NOT_FOUND);
        }