예제 #1
0
 /**
  * From {@code A|B|..|Z} alternative block build
  *
  * <pre>
  *  o->o-A->o->o (last ATNState is BlockEndState pointed to by all alts)
  *  |          ^
  *  |->o-B->o--|
  *  |          |
  *  ...        |
  *  |          |
  *  |->o-Z->o--|
  * </pre>
  *
  * So start node points at every alternative with epsilon transition and every alt right side
  * points at a block end ATNState.
  *
  * <p>Special case: only one alternative: don't make a block with alt begin/end.
  *
  * <p>Special case: if just a list of tokens/chars/sets, then collapse to a single edged o-set->o
  * graph.
  *
  * <p>TODO: Set alt number (1..n) in the states?
  */
 @NotNull
 @Override
 public Handle block(
     @NotNull BlockAST blkAST, @NotNull GrammarAST ebnfRoot, @NotNull List<Handle> alts) {
   if (ebnfRoot == null) {
     if (alts.size() == 1) {
       Handle h = alts.get(0);
       blkAST.atnState = h.left;
       return h;
     }
     BlockStartState start = newState(BasicBlockStartState.class, blkAST);
     if (alts.size() > 1) atn.defineDecisionState(start);
     return makeBlock(start, blkAST, alts);
   }
   switch (ebnfRoot.getType()) {
     case ANTLRParser.OPTIONAL:
       BlockStartState start = newState(BasicBlockStartState.class, blkAST);
       atn.defineDecisionState(start);
       Handle h = makeBlock(start, blkAST, alts);
       return optional(ebnfRoot, h);
     case ANTLRParser.CLOSURE:
       BlockStartState star = newState(StarBlockStartState.class, ebnfRoot);
       if (alts.size() > 1) atn.defineDecisionState(star);
       h = makeBlock(star, blkAST, alts);
       return star(ebnfRoot, h);
     case ANTLRParser.POSITIVE_CLOSURE:
       PlusBlockStartState plus = newState(PlusBlockStartState.class, ebnfRoot);
       if (alts.size() > 1) atn.defineDecisionState(plus);
       h = makeBlock(plus, blkAST, alts);
       return plus(ebnfRoot, h);
   }
   return null;
 }
예제 #2
0
  protected Handle makeBlock(BlockStartState start, BlockAST blkAST, List<Handle> alts) {
    BlockEndState end = newState(BlockEndState.class, blkAST);
    start.endState = end;
    for (Handle alt : alts) {
      // hook alts up to decision block
      epsilon(start, alt.left);
      epsilon(alt.right, end);
      // no back link in ATN so must walk entire alt to see if we can
      // strip out the epsilon to 'end' state
      TailEpsilonRemover opt = new TailEpsilonRemover(atn);
      opt.visit(alt.left);
    }
    Handle h = new Handle(start, end);
    //		FASerializer ser = new FASerializer(g, h.left);
    //		System.out.println(blkAST.toStringTree()+":\n"+ser);
    blkAST.atnState = start;

    return h;
  }