protected int getTokenType(GrammarAST atom) {
   int ttype;
   if (g.isLexer()) {
     ttype = CharSupport.getCharValueFromGrammarCharLiteral(atom.getText());
   } else {
     ttype = g.getTokenType(atom.getText());
   }
   return ttype;
 }
  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);
  }
 /**
  * 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);
 }