Example #1
0
 /**
  * NOTE: {@link MySQLToken#IDENTIFIER id} dosn't include <code>'.'</code> for sake of performance
  * issue (based on <i>shaojin.wensj</i>'s design). However, it is not convenient for MySQL
  * compatibility. e.g. <code>".123f"</code> will be regarded as <code>".123"</code> and <code>"f"
  * </code> in MySQL, but in this {@link MySQLLexer}, it will be <code>"."</code> and <code>"123f"
  * </code> because <code>".123f"</code> may be part of <code>"db1.123f"</code> and <code>"123f"
  * </code> is the table name.
  *
  * @param initSize how many char has already been consumed
  */
 private void scanIdentifierFromNumber(int initOffset, int initSize)
     throws SQLSyntaxErrorException {
   offsetCache = initOffset;
   sizeCache = initSize;
   for (; CharTypes.isIdentifierChar(ch); ++sizeCache) {
     scanChar();
   }
   updateStringValue(sql, offsetCache, sizeCache);
   MySQLToken tok = keywods.getKeyword(stringValueUppercase);
   token = tok == null ? MySQLToken.IDENTIFIER : tok;
 }
Example #2
0
  /**
   * if first char is <code>.</code>, token may be {@link MySQLToken#PUNC_DOT} if invalid char is
   * presented after <code>.</code>
   */
  protected void scanNumber() throws SQLSyntaxErrorException {
    offsetCache = curIndex;
    sizeCache = 1;
    final boolean fstDot = ch == '.';
    boolean dot = fstDot;
    boolean sign = false;
    int state = fstDot ? 1 : 0;

    for (; scanChar() != MySQLLexer.EOI; ++sizeCache) {
      switch (state) {
        case 0:
          if (CharTypes.isDigit(ch)) {
          } else if (ch == '.') {
            dot = true;
            state = 1;
          } else if (ch == 'e' || ch == 'E') {
            state = 3;
          } else if (CharTypes.isIdentifierChar(ch)) {
            scanIdentifierFromNumber(offsetCache, sizeCache);
            return;
          } else {
            token = MySQLToken.LITERAL_NUM_PURE_DIGIT;
            return;
          }
          break;
        case 1:
          if (CharTypes.isDigit(ch)) {
            state = 2;
          } else if (ch == 'e' || ch == 'E') {
            state = 3;
          } else if (CharTypes.isIdentifierChar(ch) && fstDot) {
            sizeCache = 1;
            ch = sql[curIndex = offsetCache + 1];
            token = MySQLToken.PUNC_DOT;
            return;
          } else {
            token = MySQLToken.LITERAL_NUM_MIX_DIGIT;
            return;
          }
          break;
        case 2:
          if (CharTypes.isDigit(ch)) {
          } else if (ch == 'e' || ch == 'E') {
            state = 3;
          } else if (CharTypes.isIdentifierChar(ch) && fstDot) {
            sizeCache = 1;
            ch = sql[curIndex = offsetCache + 1];
            token = MySQLToken.PUNC_DOT;
            return;
          } else {
            token = MySQLToken.LITERAL_NUM_MIX_DIGIT;
            return;
          }
          break;
        case 3:
          if (CharTypes.isDigit(ch)) {
            state = 5;
          } else if (ch == '+' || ch == '-') {
            sign = true;
            state = 4;
          } else if (fstDot) {
            sizeCache = 1;
            ch = sql[curIndex = offsetCache + 1];
            token = MySQLToken.PUNC_DOT;
            return;
          } else if (!dot) {
            if (CharTypes.isIdentifierChar(ch)) {
              scanIdentifierFromNumber(offsetCache, sizeCache);
            } else {
              updateStringValue(sql, offsetCache, sizeCache);
              MySQLToken tok = keywods.getKeyword(stringValueUppercase);
              token = tok == null ? MySQLToken.IDENTIFIER : tok;
            }
            return;
          } else {
            throw err("invalid char after '.' and 'e' for as part of number: " + ch);
          }
          break;
        case 4:
          if (CharTypes.isDigit(ch)) {
            state = 5;
            break;
          } else if (fstDot) {
            sizeCache = 1;
            ch = sql[curIndex = offsetCache + 1];
            token = MySQLToken.PUNC_DOT;
          } else if (!dot) {
            ch = sql[--curIndex];
            --sizeCache;
            updateStringValue(sql, offsetCache, sizeCache);
            MySQLToken tok = keywods.getKeyword(stringValueUppercase);
            token = tok == null ? MySQLToken.IDENTIFIER : tok;
          } else {
            throw err("expect digit char after SIGN for 'e': " + ch);
          }
          return;
        case 5:
          if (CharTypes.isDigit(ch)) {
            break;
          } else if (CharTypes.isIdentifierChar(ch)) {
            if (fstDot) {
              sizeCache = 1;
              ch = sql[curIndex = offsetCache + 1];
              token = MySQLToken.PUNC_DOT;
            } else if (!dot) {
              if (sign) {
                ch = sql[curIndex = offsetCache];
                scanIdentifierFromNumber(curIndex, 0);
              } else {
                scanIdentifierFromNumber(offsetCache, sizeCache);
              }
            } else {
              token = MySQLToken.LITERAL_NUM_MIX_DIGIT;
            }
          } else {
            token = MySQLToken.LITERAL_NUM_MIX_DIGIT;
          }
          return;
      }
    }
    switch (state) {
      case 0:
        token = MySQLToken.LITERAL_NUM_PURE_DIGIT;
        return;
      case 1:
        if (fstDot) {
          token = MySQLToken.PUNC_DOT;
          return;
        }
      case 2:
      case 5:
        token = MySQLToken.LITERAL_NUM_MIX_DIGIT;
        return;
      case 3:
        if (fstDot) {
          sizeCache = 1;
          ch = sql[curIndex = offsetCache + 1];
          token = MySQLToken.PUNC_DOT;
        } else if (!dot) {
          updateStringValue(sql, offsetCache, sizeCache);
          MySQLToken tok = keywods.getKeyword(stringValueUppercase);
          token = tok == null ? MySQLToken.IDENTIFIER : tok;
        } else {
          throw err("expect digit char after SIGN for 'e': " + ch);
        }
        return;
      case 4:
        if (fstDot) {
          sizeCache = 1;
          ch = sql[curIndex = offsetCache + 1];
          token = MySQLToken.PUNC_DOT;
        } else if (!dot) {
          ch = sql[--curIndex];
          --sizeCache;
          updateStringValue(sql, offsetCache, sizeCache);
          MySQLToken tok = keywods.getKeyword(stringValueUppercase);
          token = tok == null ? MySQLToken.IDENTIFIER : tok;
        } else {
          throw err("expect digit char after SIGN for 'e': " + ch);
        }
        return;
    }
  }