예제 #1
0
 @Override
 public void visitState(ATNState p) {
   if (p.getClass() == ATNState.class && p.getNumberOfTransitions() == 1) {
     ATNState q = p.transition(0).target;
     if (p.transition(0) instanceof RuleTransition) {
       q = ((RuleTransition) p.transition(0)).followState;
     }
     if (q.getClass() == ATNState.class) {
       // we have p-x->q for x in {rule, action, pred, token, ...}
       // if edge out of q is single epsilon to block end
       // we can strip epsilon p-x->q-eps->r
       Transition trans = q.transition(0);
       if (q.getNumberOfTransitions() == 1
           && trans.isEpsilon()
           && !(trans instanceof ActionTransition)) {
         ATNState r = trans.target;
         if (r instanceof BlockEndState
             || r instanceof PlusLoopbackState
             || r instanceof StarLoopbackState) {
           // skip over q
           if (p.transition(0) instanceof RuleTransition) {
             ((RuleTransition) p.transition(0)).followState = r;
           } else {
             p.transition(0).target = r;
           }
           atn.removeState(q);
         }
       }
     }
   }
 }
예제 #2
0
 public void addRuleFollowLinks() {
   for (ATNState p : atn.states) {
     if (p != null
         && p.getStateType() == ATNState.BASIC
         && p.getNumberOfTransitions() == 1
         && p.transition(0) instanceof RuleTransition) {
       RuleTransition rt = (RuleTransition) p.transition(0);
       addFollowLink(rt.ruleIndex, rt.followState);
     }
   }
 }
예제 #3
0
 /**
  * Add an EOF transition to any rule end ATNState that points to nothing (i.e., for all those
  * rules not invoked by another rule). These are start symbols then.
  *
  * <p>Return the number of grammar entry points; i.e., how many rules are not invoked by another
  * rule (they can only be invoked from outside). These are the start rules.
  */
 public int addEOFTransitionToStartRules() {
   int n = 0;
   ATNState eofTarget = newState(null); // one unique EOF target for all rules
   for (Rule r : g.rules.values()) {
     ATNState stop = atn.ruleToStopState[r.index];
     if (stop.getNumberOfTransitions() > 0) continue;
     n++;
     Transition t = new AtomTransition(eofTarget, Token.EOF);
     stop.addTransition(t);
   }
   return n;
 }
예제 #4
0
 protected void epsilon(ATNState a, @NotNull ATNState b, boolean prepend) {
   if (a != null) {
     int index = prepend ? 0 : a.getNumberOfTransitions();
     a.addTransition(index, new EpsilonTransition(b));
   }
 }