/** From an alt number associated with artificial Tokens rule, return * the name of the token that is associated with that alt. */ public virtual String GetTokenNameForTokensRuleAlt(int alt) { NFAState decisionState = dfa.NFADecisionStartState; NFAState altState = dfa.nfa.grammar.GetNFAStateForAltOfDecision(decisionState, alt); NFAState decisionLeft = (NFAState)altState.transition[0].target; RuleClosureTransition ruleCallEdge = (RuleClosureTransition)decisionLeft.transition[0]; NFAState ruleStartState = (NFAState)ruleCallEdge.target; //[email protected]("alt = "+decisionLeft.getEnclosingRule()); return(ruleStartState.enclosingRule.Name); }
private void ComputeAltToProblemMaps(IEnumerable <int> dfaStatesUnaliased, IDictionary <int, IList <NFAConfiguration> > configurationsMap, IDictionary <int, IDictionary <string, ICollection <NFAState> > > altToTargetToCallSitesMap, IDictionary <int, DFAState> altToDFAState) { foreach (int stateI in dfaStatesUnaliased) { // walk this DFA's config list IList <NFAConfiguration> configs; configurationsMap.TryGetValue(stateI, out configs); for (int i = 0; i < configs.Count; i++) { NFAConfiguration c = (NFAConfiguration)configs[i]; NFAState ruleInvocationState = _dfa.Nfa.GetState(c.State); Transition transition0 = ruleInvocationState.transition[0]; RuleClosureTransition @ref = (RuleClosureTransition)transition0; string targetRule = ((NFAState)@ref.Target).enclosingRule.Name; int altI = c.Alt; IDictionary <string, ICollection <NFAState> > targetToCallSiteMap; altToTargetToCallSitesMap.TryGetValue(altI, out targetToCallSiteMap); if (targetToCallSiteMap == null) { targetToCallSiteMap = new Dictionary <string, ICollection <NFAState> >(); altToTargetToCallSitesMap[altI] = targetToCallSiteMap; } ICollection <NFAState> callSites; targetToCallSiteMap.TryGetValue(targetRule, out callSites); if (callSites == null) { callSites = new HashSet <NFAState>(); targetToCallSiteMap[targetRule] = callSites; } callSites.Add(ruleInvocationState); // track one problem DFA state per alt DFAState state; if (!altToDFAState.TryGetValue(altI, out state) || state == null) { DFAState sampleBadState = _dfa.GetState(stateI); altToDFAState[altI] = sampleBadState; } } } }
/** For reference to rule r, build * * o-e->(r) o * * where (r) is the start of rule r and the trailing o is not linked * to from rule ref state directly (it's done thru the transition(0) * RuleClosureTransition. * * If the rule r is just a list of tokens, it's block will be just * a set on an edge o->o->o-set->o->o->o, could inline it rather than doing * the rule reference, but i'm not doing this yet as I'm not sure * it would help much in the NFA->DFA construction. * * TODO add to codegen: collapse alt blks that are sets into single matchSet */ public virtual StateCluster BuildRuleRef( Rule refDef, NFAState ruleStart ) { //System.Console.Out.WriteLine( "building ref to rule " + nfa.grammar.name + "." + refDef.name ); NFAState left = NewState(); //left.Description = "ref to " + ruleStart.Description; NFAState right = NewState(); //right.Description = "NFAState following ref to " + ruleStart.Description; Transition e = new RuleClosureTransition( refDef, ruleStart, right ); left.AddTransition( e ); StateCluster g = new StateCluster( left, right ); return g; }
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); }
protected virtual LookaheadSet FirstCore(NFAState s, bool chaseFollowTransitions) { /* * [email protected]("_LOOK("+s+") in rule "+s.enclosingRule); * if ( s.transition[0] instanceof RuleClosureTransition ) { * [email protected]("go to rule "+((NFAState)s.transition[0].target).enclosingRule); * } */ 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(new LookaheadSet(IntervalSet.COMPLETE_SET)); } return(new LookaheadSet(Label.EOR_TOKEN_TYPE)); } if (_lookBusy.Contains(s)) { // return a copy of an empty set; we may modify set inline return(new LookaheadSet()); } _lookBusy.Add(s); Transition transition0 = s.transition[0]; if (transition0 == null) { return(null); } if (transition0.label.IsAtom) { int atom = transition0.label.Atom; return(new LookaheadSet(atom)); } if (transition0.label.IsSet) { IIntSet sl = transition0.label.Set; return(new LookaheadSet(sl)); } // compute FIRST of transition 0 LookaheadSet tset = null; // if transition 0 is a rule call and we don't want FOLLOW, check cache if (!chaseFollowTransitions && transition0 is RuleClosureTransition) { LookaheadSet prev = _firstCache.get((NFAState)transition0.target); if (prev != null) { tset = new LookaheadSet(prev); } } // if not in cache, must compute if (tset == null) { tset = FirstCore((NFAState)transition0.target, chaseFollowTransitions); // save FIRST cache for transition 0 if rule call if (!chaseFollowTransitions && transition0 is RuleClosureTransition) { _firstCache[(NFAState)transition0.target] = tset; } } // did we fall off the end? if (_grammar.type != GrammarType.Lexer && tset.Member(Label.EOR_TOKEN_TYPE)) { 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; // remove the EOR and get what follows //tset.remove(Label.EOR_TOKEN_TYPE); NFAState following = (NFAState)ruleInvocationTrans.followState; LookaheadSet fset = FirstCore(following, chaseFollowTransitions); fset.OrInPlace(tset); // tset cached; or into new set fset.Remove(Label.EOR_TOKEN_TYPE); tset = fset; } } Transition transition1 = s.transition[1]; if (transition1 != null) { LookaheadSet tset1 = FirstCore((NFAState)transition1.target, chaseFollowTransitions); tset1.OrInPlace(tset); // tset cached; or into new set tset = tset1; } return(tset); }