Ejemplo n.º 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);
  }
Ejemplo n.º 2
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);
 }
Ejemplo n.º 3
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);
  }
Ejemplo n.º 4
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);
 }
Ejemplo n.º 5
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;
 }
Ejemplo n.º 6
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;
 }
Ejemplo n.º 7
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);
  }
Ejemplo n.º 8
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);
 }
Ejemplo n.º 9
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;
 }