Beispiel #1
0
  protected SemanticContext _getPredicates(NFAState s, NFAState altStartState) {
    // System.out.println("_getPredicates("+s+")");
    if (s.isAcceptState()) {
      return null;
    }

    // avoid infinite loops from (..)* etc...
    if (lookBusy.contains(s)) {
      return null;
    }
    lookBusy.add(s);

    Transition transition0 = s.transition[0];
    // no transitions
    if (transition0 == null) {
      return null;
    }

    // not a predicate and not even an epsilon
    if (!(transition0.label.isSemanticPredicate() || transition0.label.isEpsilon())) {
      return null;
    }

    SemanticContext p = null;
    SemanticContext p0 = null;
    SemanticContext p1 = null;
    if (transition0.label.isSemanticPredicate()) {
      // System.out.println("pred "+transition0.label);
      p = transition0.label.getSemanticContext();
      // ignore backtracking preds not on left edge for this decision
      if (((SemanticContext.Predicate) p).predicateAST.getType() == ANTLRParser.BACKTRACK_SEMPRED
          && s == altStartState.transition[0].target) {
        p = null; // don't count
      }
    }

    // get preds from beyond this state
    p0 = _getPredicates((NFAState) transition0.target, altStartState);

    // get preds from other transition
    Transition transition1 = s.transition[1];
    if (transition1 != null) {
      p1 = _getPredicates((NFAState) transition1.target, altStartState);
    }

    // join this&following-right|following-down
    return SemanticContext.and(p, SemanticContext.or(p0, p1));
  }
Beispiel #2
0
  protected int _detectConfoundingPredicates(
      NFAState s, Rule enclosingRule, boolean chaseFollowTransitions) {
    // System.out.println("_detectNonAutobacktrackPredicates("+s+")");
    if (!chaseFollowTransitions && s.isAcceptState()) {
      if (grammar.type == Grammar.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()) {
      // System.out.println("pred "+transition0.label);
      SemanticContext ctx = transition0.label.getSemanticContext();
      SemanticContext.Predicate p = (SemanticContext.Predicate) ctx;
      if (p.predicateAST.getType() != ANTLRParser.BACKTRACK_SEMPRED) {
        return DETECT_PRED_FOUND;
      }
    }

    /*
    if ( transition0.label.isSemanticPredicate() ) {
    	System.out.println("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) )
    	{
    		System.out.println("found pred "+p+" not in "+enclosingRule.name);
    		return DETECT_PRED_FOUND;
    	}
    }
    */

    int result =
        _detectConfoundingPredicates(
            (NFAState) transition0.target, enclosingRule, chaseFollowTransitions);
    if (result == DETECT_PRED_FOUND) {
      return DETECT_PRED_FOUND;
    }

    if (result == DETECT_PRED_EOR) {
      if (transition0 instanceof 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 =
            _detectConfoundingPredicates(following, enclosingRule, chaseFollowTransitions);
        if (afterRuleResult == DETECT_PRED_FOUND) {
          return DETECT_PRED_FOUND;
        }
      }
    }

    Transition transition1 = s.transition[1];
    if (transition1 != null) {
      int t1Result =
          _detectConfoundingPredicates(
              (NFAState) transition1.target, enclosingRule, chaseFollowTransitions);
      if (t1Result == DETECT_PRED_FOUND) {
        return DETECT_PRED_FOUND;
      }
    }

    return DETECT_PRED_NOT_FOUND;
  }
Beispiel #3
0
  protected LookaheadSet _FIRST(NFAState s, boolean chaseFollowTransitions) {
    /*
    System.out.println("_LOOK("+s+") in rule "+s.enclosingRule);
    if ( s.transition[0] instanceof RuleClosureTransition ) {
    	System.out.println("go to rule "+((NFAState)s.transition[0].target).enclosingRule);
    }
    */
    if (!chaseFollowTransitions && s.isAcceptState()) {
      if (grammar.type == Grammar.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.getAtom();
      return new LookaheadSet(atom);
    }
    if (transition0.label.isSet()) {
      IntSet sl = transition0.label.getSet();
      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 instanceof 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 = _FIRST((NFAState) transition0.target, chaseFollowTransitions);
      // save FIRST cache for transition 0 if rule call
      if (!chaseFollowTransitions && transition0 instanceof RuleClosureTransition) {
        FIRSTCache.put((NFAState) transition0.target, tset);
      }
    }

    // did we fall off the end?
    if (grammar.type != Grammar.LEXER && tset.member(Label.EOR_TOKEN_TYPE)) {
      if (transition0 instanceof 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 = _FIRST(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 = _FIRST((NFAState) transition1.target, chaseFollowTransitions);
      tset1.orInPlace(tset); // tset cached; or into new set
      tset = tset1;
    }

    return tset;
  }