public Token nextToken() throws ParseException {
    if (currentChar == -1) {
      return new Token(TokenType.EOF, "");
    }
    if (isWhitespace(currentChar)) {
      if (ignoreWhitespace) {
        parseWhitespace();
        return nextToken();
      } else {
        return parseWhitespace();
      }
    }
    for (TokenType tt : TokenType.values()) {
      String text = tt.getText();
      if (text != null && text.length() == 1 && currentChar == text.charAt(0)) {
        nextChar();
        return new Token(tt, null);
      }
    }
    if (isIdentifierStart(currentChar)) {
      return parseIdentifier();
    }
    if (isDigit(currentChar)) {
      return parseNumber();
    }
    throw new SyntaxException("Syntax error: unexpected symbol '" + (char)currentChar + "'", text, index);
  }