/**
  * 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;
 }
Example #2
0
 public boolean isGreedy(@NotNull BlockAST blkAST) {
   boolean greedy = true;
   String greedyOption = blkAST.getOptionString("greedy");
   if (blockHasWildcardAlt(blkAST) || greedyOption != null && greedyOption.equals("false")) {
     greedy = false;
   }
   return greedy;
 }
  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;
  }
 /**
  *
  *
  * <pre>
  * (RULE e int _p (returns int v)
  * 	(BLOCK
  * 	  (ALT
  * 		(BLOCK
  * 			(ALT INT {$v = $INT.int;})
  * 			(ALT '(' (= x e) ')' {$v = $x.v;})
  * 			(ALT ID))
  * 		(* (BLOCK
  * 		(OPTIONS ...)
  * 			(ALT {7 >= $_p}? '*' (= b e) {$v = $a.v * $b.v;})
  * 			(ALT {6 >= $_p}? '+' (= b e) {$v = $a.v + $b.v;})
  * 			(ALT {3 >= $_p}? '++') (ALT {2 >= $_p}? '--'))))))
  * </pre>
  */
 public void setAltASTPointers(LeftRecursiveRule r, RuleAST t) {
   //		System.out.println("RULE: "+t.toStringTree());
   BlockAST ruleBlk = (BlockAST) t.getFirstChildWithType(ANTLRParser.BLOCK);
   AltAST mainAlt = (AltAST) ruleBlk.getChild(0);
   BlockAST primaryBlk = (BlockAST) mainAlt.getChild(0);
   BlockAST opsBlk = (BlockAST) mainAlt.getChild(1).getChild(0); // (* BLOCK ...)
   for (int i = 0; i < r.recPrimaryAlts.size(); i++) {
     LeftRecursiveRuleAltInfo altInfo = r.recPrimaryAlts.get(i);
     altInfo.altAST = (AltAST) primaryBlk.getChild(i);
     altInfo.altAST.leftRecursiveAltInfo = altInfo;
     altInfo.originalAltAST.leftRecursiveAltInfo = altInfo;
     //			altInfo.originalAltAST.parent = altInfo.altAST.parent;
     //			System.out.println(altInfo.altAST.toStringTree());
   }
   for (int i = 0; i < r.recOpAlts.size(); i++) {
     LeftRecursiveRuleAltInfo altInfo = r.recOpAlts.getElement(i);
     altInfo.altAST = (AltAST) opsBlk.getChild(i);
     altInfo.altAST.leftRecursiveAltInfo = altInfo;
     altInfo.originalAltAST.leftRecursiveAltInfo = altInfo;
     //			altInfo.originalAltAST.parent = altInfo.altAST.parent;
     //			System.out.println(altInfo.altAST.toStringTree());
   }
 }