예제 #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
 @NotNull
 public Handle elemList(@NotNull List<Handle> els) {
   int n = els.size();
   for (int i = 0; i < n - 1; i++) { // hook up elements (visit all but last)
     Handle el = els.get(i);
     // if el is of form o-x->o for x in {rule, action, pred, token, ...}
     // and not last in alt
     Transition tr = null;
     if (el.left.getNumberOfTransitions() == 1) tr = el.left.transition(0);
     boolean isRuleTrans = tr instanceof RuleTransition;
     if (el.left.getClass() == ATNState.class
         && el.right.getClass() == ATNState.class
         && tr != null
         && (isRuleTrans || tr.target == el.right)) {
       // we can avoid epsilon edge to next el
       if (isRuleTrans) ((RuleTransition) tr).followState = els.get(i + 1).left;
       else tr.target = els.get(i + 1).left;
       atn.removeState(el.right); // we skipped over this state
     } else { // need epsilon if previous block's right end node is complicated
       epsilon(el.right, els.get(i + 1).left);
     }
   }
   Handle first = els.get(0);
   Handle last = els.get(n - 1);
   if (first == null || last == null) {
     g.tool.errMgr.toolError(ErrorType.INTERNAL_ERROR, "element list has first|last == null");
   }
   return new Handle(first.left, last.right);
 }