public IntervalSet getSetFromCharSetLiteral(GrammarAST charSetAST) {
    String chars = charSetAST.getText();
    chars = chars.substring(1, chars.length() - 1);
    String cset = '"' + chars + '"';
    IntervalSet set = new IntervalSet();

    // unescape all valid escape char like \n, leaving escaped dashes as '\-'
    // so we can avoid seeing them as '-' range ops.
    chars = CharSupport.getStringFromGrammarStringLiteral(cset);
    // now make x-y become set of char
    int n = chars.length();
    for (int i = 0; i < n; i++) {
      int c = chars.charAt(i);
      if (c == '\\' && (i + 1) < n && chars.charAt(i + 1) == '-') { // \-
        set.add('-');
        i++;
      } else if ((i + 2) < n && chars.charAt(i + 1) == '-') { // range x-y
        int x = c;
        int y = chars.charAt(i + 2);
        if (x <= y) set.add(x, y);
        i += 2;
      } else {
        set.add(c);
      }
    }
    return set;
  }
 /**
  * For a lexer, a string is a sequence of char to match. That is, "fog" is treated as 'f' 'o' 'g'
  * not as a single transition in the DFA. Machine== o-'f'-&gt;o-'o'-&gt;o-'g'-&gt;o and has n+1
  * states for n characters.
  */
 @Override
 public Handle stringLiteral(TerminalAST stringLiteralAST) {
   String chars = stringLiteralAST.getText();
   chars = CharSupport.getStringFromGrammarStringLiteral(chars);
   int n = chars.length();
   ATNState left = newState(stringLiteralAST);
   ATNState prev = left;
   ATNState right = null;
   for (int i = 0; i < n; i++) {
     right = newState(stringLiteralAST);
     prev.addTransition(new AtomTransition(right, chars.charAt(i)));
     prev = right;
   }
   stringLiteralAST.atnState = left;
   return new Handle(left, right);
 }