Пример #1
0
 public LookaheadSet LOOK(NFAState s) {
   if (NFAToDFAConverter.debug) {
     System.out.println("> LOOK(" + s + ")");
   }
   lookBusy.clear();
   LookaheadSet look = _FIRST(s, true);
   // FOLLOW makes no sense (at the moment!) for lexical rules.
   if (grammar.type != Grammar.LEXER && look.member(Label.EOR_TOKEN_TYPE)) {
     // avoid altering FIRST reset as it is cached
     LookaheadSet f = FOLLOW(s.enclosingRule);
     f.orInPlace(look);
     f.remove(Label.EOR_TOKEN_TYPE);
     look = f;
     // look.orInPlace(FOLLOW(s.enclosingRule));
   } else if (grammar.type == Grammar.LEXER && look.member(Label.EOT)) {
     // if this has EOT, lookahead is all char (all char can follow rule)
     // look = new LookaheadSet(Label.EOT);
     look = new LookaheadSet(IntervalSet.COMPLETE_SET);
   }
   if (NFAToDFAConverter.debug) {
     System.out.println("< LOOK(" + s + ")=" + look.toString(grammar));
   }
   return look;
 }
Пример #2
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;
  }