/**
   * Liest einen Identifier aus und gibt diesen als String zurck. <br>
   * EBNF:<br>
   * <code>(letter | "_") {letter | "_"|digit};</code>
   *
   * @param firstCanBeNumber
   * @return Identifier.
   */
  private String identifier(boolean firstCanBeNumber) {
    // int start = cfml.getPos();
    if (!cfml.isCurrentLetter() && !cfml.isCurrentSpecial()) {
      if (!firstCanBeNumber) return null;
      else if (!cfml.isCurrentDigit()) return null;
    }

    StringBuffer sb = new StringBuffer();
    // if(CASE_TYPE_UPPER==caseType)
    sb.append(cfml.getCurrentUpper());
    /*else if(CASE_TYPE_ORIGINAL==caseType)
    	sb.append(cfml.getCurrent());
    else
    	sb.append(cfml.getCurrentLower());*/
    do {
      cfml.next();
      if (!(cfml.isCurrentLetter() || cfml.isCurrentDigit() || cfml.isCurrentSpecial())) {
        break;
      }

      // if(CASE_TYPE_UPPER==caseType)
      sb.append(cfml.getCurrentUpper());
      /*else if(CASE_TYPE_ORIGINAL==caseType)
      	sb.append(cfml.getCurrent());
      else
      	sb.append(cfml.getCurrentLower());*/

    } while (cfml.isValidIndex());
    return sb.toString(); // cfml.substringLower(start,cfml.getPos()-start);
  }
  /**
   * Transfomiert einen numerische Wert. Die L¦nge des numerischen Wertes interessiert nicht zu
   * ᅵbersetzungszeit, ein "Overflow" fhrt zu einem Laufzeitfehler. Da die zu erstellende CFXD,
   * bzw. dieser Transfomer, keine Vorwegnahme des Laufzeitsystems vornimmt. <br>
   * EBNF:<br>
   * <code>["+"|"-"] digit {digit} {"." digit {digit}};</code>
   *
   * @return CFXD Element
   * @throws PageException
   */
  private Ref number() throws PageException {
    // check first character is a number literal representation
    // if(!cfml.isCurrentDigit()) return null;

    StringBuffer rtn = new StringBuffer(6);

    // get digit on the left site of the dot
    if (cfml.isCurrent('.')) rtn.append('0');
    else digit(rtn);
    // read dot if exist
    if (cfml.forwardIfCurrent('.')) {
      rtn.append('.');
      int before = cfml.getPos();
      digit(rtn);

      if (before < cfml.getPos() && cfml.forwardIfCurrent('e')) {
        if (cfml.isCurrentDigit()) {
          rtn.append('e');
          digit(rtn);
        } else {
          cfml.previous();
        }
      }

      // read right side of the dot
      if (before == cfml.getPos()) throw new ExpressionException("Number can't end with [.]");
      // rtn.append(rightSite);
    }
    cfml.removeSpace();
    mode = STATIC;
    return new LNumber(rtn.toString());
  }
  /**
   * Liest die reinen Zahlen innerhalb des CFMLString aus und gibt diese als Zeichenkette zurck.
   * <br>
   * EBNF:<br>
   * <code>"0"|..|"9";</code>
   *
   * @param rtn
   */
  private void digit(StringBuffer rtn) {

    while (cfml.isValidIndex()) {
      if (!cfml.isCurrentDigit()) break;
      rtn.append(cfml.getCurrentLower());
      cfml.next();
    }
  }
  /**
   * Hier werden die verschiedenen M￶glichen Werte erkannt und jenachdem wird mit der passenden
   * Methode weitergefahren <br>
   * EBNF:<br>
   * <code>string | number | dynamic | sharp;</code>
   *
   * @return CFXD Element
   * @throws PageException
   */
  private Ref checker() throws PageException {

    Ref ref = null;
    // String
    if (cfml.isCurrentQuoter()) {
      // mode=STATIC; is at the end of the string function because must set after execution
      return string();
    }
    // Number
    if (cfml.isCurrentDigit() || cfml.isCurrent('.')) {
      // mode=STATIC; is at the end of the string function because must set after execution
      return number();
    }
    // Dynamic
    if ((ref = dynamic()) != null) {
      mode = DYNAMIC;
      return ref;
    }
    // Sharp
    if ((ref = sharp()) != null) {
      mode = DYNAMIC;
      return ref;
    }
    // JSON
    if ((ref = json(JSON_ARRAY, '[', ']')) != null) {
      mode = DYNAMIC;
      return ref;
    }
    if ((ref = json(JSON_STRUCT, '{', '}')) != null) {
      mode = DYNAMIC;
      return ref;
    }

    if (cfml.isAfterLast() && cfml.toString().trim().length() == 0) return new LString("");

    // else Error
    throw new ExpressionException(
        "Syntax Error, Invalid Construct",
        "at position " + cfml.getPos() + " in [" + cfml.toString() + "]");
  }