示例#1
0
  /**
   * From (blk)* build ( blk+ )? with *two* decisions, one for entry and one for choosing alts of
   * blk.
   *
   * <p>|-------------| v | o--[o-blk-o]->o o | ^ -----------------|
   *
   * <p>Note that the optional bypass must jump outside the loop as (A|B)* is not the same thing as
   * (A|B|)+.
   */
  @NotNull
  public Handle star(@NotNull GrammarAST starAST, @NotNull Handle elem) {
    StarBlockStartState blkStart = (StarBlockStartState) elem.left;
    BlockEndState blkEnd = (BlockEndState) elem.right;

    StarLoopEntryState entry = newState(StarLoopEntryState.class, starAST);
    atn.defineDecisionState(entry);
    LoopEndState end = newState(LoopEndState.class, starAST);
    StarLoopbackState loop = newState(StarLoopbackState.class, starAST);
    entry.loopBackState = loop;
    end.loopBackStateNumber = loop.stateNumber;

    BlockAST blkAST = (BlockAST) starAST.getChild(0);
    entry.isGreedy = isGreedy(blkAST);
    if (!g.isLexer() || entry.isGreedy) {
      epsilon(entry, blkStart); // loop enter edge (alt 1)
      epsilon(entry, end); // bypass loop edge (alt 2)
    } else { // only lexers flip entry/exit branches for nongreedy
      // if not greedy, priority to exit branch; make it first
      epsilon(entry, end); // bypass loop edge (alt 1)
      epsilon(entry, blkStart); // loop enter edge (alt 2)
    }
    epsilon(blkEnd, loop); // block end hits loop back
    epsilon(loop, entry); // loop back to entry/exit decision

    starAST.atnState = entry; // decision is to enter/exit; blk is its own decision
    return new Handle(entry, end);
  }
示例#2
0
  /**
   * From (blk)+ build
   *
   * <p>|---------| v | [o-blk-o]->o->o
   *
   * <p>We add a decision for loop back node to the existing one at blk start.
   */
  @NotNull
  public Handle plus(@NotNull GrammarAST plusAST, @NotNull Handle blk) {
    PlusBlockStartState blkStart = (PlusBlockStartState) blk.left;
    BlockEndState blkEnd = (BlockEndState) blk.right;

    PlusLoopbackState loop = newState(PlusLoopbackState.class, plusAST);
    atn.defineDecisionState(loop);
    LoopEndState end = newState(LoopEndState.class, plusAST);
    blkStart.loopBackState = loop;
    end.loopBackStateNumber = loop.stateNumber;

    plusAST.atnState = blkStart;
    epsilon(blkEnd, loop); // blk can see loop back

    BlockAST blkAST = (BlockAST) plusAST.getChild(0);
    loop.isGreedy = isGreedy(blkAST);
    if (!g.isLexer() || loop.isGreedy) {
      epsilon(loop, blkStart); // loop back to start
      epsilon(loop, end); // or exit
    } else { // only lexers flip entry/exit branches for nongreedy
      // if not greedy, priority to exit branch; make it first
      epsilon(loop, end); // exit
      epsilon(loop, blkStart); // loop back to start
    }

    return new Handle(blkStart, end);
  }
示例#3
0
 protected int getTokenType(GrammarAST atom) {
   int ttype;
   if (g.isLexer()) {
     ttype = CharSupport.getCharValueFromGrammarCharLiteral(atom.getText());
   } else {
     ttype = g.getTokenType(atom.getText());
   }
   return ttype;
 }
示例#4
0
  public Handle _ruleRef(GrammarAST node) {
    Rule r = g.getRule(node.getText());
    if (r == null) {
      g.tool.errMgr.toolError(ErrorType.INTERNAL_ERROR, "Rule " + node.getText() + " undefined");
      return null;
    }
    RuleStartState start = atn.ruleToStartState[r.index];
    ATNState left = newState(node);
    ATNState right = newState(node);
    RuleTransition call = new RuleTransition(start, r.index, right);
    left.addTransition(call);

    node.atnState = left;
    return new Handle(left, right);
  }
示例#5
0
 /**
  * From A|B|..|Z alternative block build
  *
  * <p>o->o-A->o->o (last ATNState is BlockEndState pointed to by all alts) | ^ |->o-B->o--| | |
  * ... | | | |->o-Z->o--|
  *
  * <p>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 edge'd o-set->o
  * graph.
  *
  * <p>TODO: Set alt number (1..n) in the states?
  */
 public Handle block(BlockAST blkAST, GrammarAST ebnfRoot, List<Handle> alts) {
   if (ebnfRoot == null) {
     if (alts.size() == 1) {
       Handle h = alts.get(0);
       blkAST.atnState = h.left;
       return h;
     }
     BlockStartState start = newState(BlockStartState.class, blkAST);
     if (alts.size() > 1) atn.defineDecisionState(start);
     return makeBlock(start, blkAST, alts);
   }
   switch (ebnfRoot.getType()) {
     case ANTLRParser.OPTIONAL:
       BlockStartState start = newState(BlockStartState.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;
 }
示例#6
0
 /** From an empty alternative build o-e->o */
 public Handle epsilon(GrammarAST node) {
   ATNState left = newState(node);
   ATNState right = newState(node);
   epsilon(left, right);
   node.atnState = left;
   return new Handle(left, right);
 }
示例#7
0
 /** Build an atom with all possible values in its label */
 @NotNull
 public Handle wildcard(GrammarAST node) {
   ATNState left = newState(node);
   ATNState right = newState(node);
   left.addTransition(new WildcardTransition(right));
   node.atnState = left;
   return new Handle(left, right);
 }
示例#8
0
 /**
  * From (A)? build either:
  *
  * <p>o--A->o | ^ o---->|
  *
  * <p>or, if A is a block, just add an empty alt to the end of the block
  */
 @NotNull
 public Handle optional(@NotNull GrammarAST optAST, @NotNull Handle blk) {
   // TODO: no such thing as nongreedy ()? so give error
   BlockStartState blkStart = (BlockStartState) blk.left;
   epsilon(blkStart, blk.right);
   optAST.atnState = blk.left;
   return blk;
 }
示例#9
0
 /**
  * From set build single edge graph o->o-set->o. To conform to what an alt block looks like, must
  * have extra state on left. This handles ~A also, converted to ~{A} set.
  */
 public Handle set(GrammarAST associatedAST, List<GrammarAST> terminals, boolean invert) {
   ATNState left = newState(associatedAST);
   ATNState right = newState(associatedAST);
   IntervalSet set = new IntervalSet();
   for (GrammarAST t : terminals) {
     int ttype = g.getTokenType(t.getText());
     set.add(ttype);
   }
   if (invert) {
     IntervalSet notSet = set.complement(Token.MIN_TOKEN_TYPE, g.getMaxTokenType());
     left.addTransition(new NotSetTransition(right, set, notSet));
   } else {
     left.addTransition(new SetTransition(right, set));
   }
   associatedAST.atnState = left;
   return new Handle(left, right);
 }
示例#10
0
 /* start->ruleblock->end */
 public Handle rule(GrammarAST ruleAST, String name, Handle blk) {
   Rule r = g.getRule(name);
   RuleStartState start = atn.ruleToStartState[r.index];
   epsilon(start, blk.left);
   RuleStopState stop = atn.ruleToStopState[r.index];
   epsilon(blk.right, stop);
   Handle h = new Handle(start, stop);
   //		ATNPrinter ser = new ATNPrinter(g, h.left);
   //		System.out.println(ruleAST.toStringTree()+":\n"+ser.asString());
   ruleAST.atnState = start;
   return h;
 }
示例#11
0
 // (BLOCK (ALT .)) or (BLOCK (ALT 'a') (ALT .))
 public static boolean blockHasWildcardAlt(@NotNull GrammarAST block) {
   for (Object alt : block.getChildren()) {
     if (!(alt instanceof AltAST)) continue;
     AltAST altAST = (AltAST) alt;
     if (altAST.getChildCount() == 1) {
       Tree e = altAST.getChild(0);
       if (e.getType() == ANTLRParser.WILDCARD) {
         return true;
       }
     }
   }
   return false;
 }
示例#12
0
 protected Handle makeBlock(BlockStartState start, GrammarAST 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();
     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;
 }