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); }
/** 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); }
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); }