use of com.alibaba.cobar.parser.recognizer.mysql.MySQLToken in project cobar by alibaba.
the class MySQLLexer method nextToken.
public MySQLToken nextToken() throws SQLSyntaxErrorException {
if (tokenCache2 != null) {
tokenCache2 = null;
return tokenCache;
}
if (tokenCache != null) {
tokenCache = null;
return token;
}
if (token == MySQLToken.EOF) {
throw new SQLSyntaxErrorException("eof for sql is already reached, cannot get new token");
}
MySQLToken t;
do {
skipSeparator();
t = nextTokenInternal();
} while (inCStyleComment && inCStyleCommentIgnore || MySQLToken.PUNC_C_STYLE_COMMENT_END == t);
return t;
}
use of com.alibaba.cobar.parser.recognizer.mysql.MySQLToken in project cobar by alibaba.
the class MySQLLexer method scanIdentifierFromNumber.
/**
* 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;
}
use of com.alibaba.cobar.parser.recognizer.mysql.MySQLToken in project cobar by alibaba.
the class MySQLExprParser method expression.
/**
* first token of this expression has been scanned, not yet consumed
*/
public Expression expression() throws SQLSyntaxErrorException {
MySQLToken token = lexer.token();
if (token == null) {
token = lexer.nextToken();
}
if (token == EOF) {
err("unexpected EOF");
}
Expression left = logicalOrExpression();
if (lexer.token() == OP_ASSIGN) {
lexer.nextToken();
Expression right = expression();
return new AssignmentExpression(left, right).setCacheEvalRst(cacheEvalRst);
}
return left;
}
use of com.alibaba.cobar.parser.recognizer.mysql.MySQLToken in project cobar by alibaba.
the class MySQLLexer method scanNumber.
/**
* 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;
}
}
Aggregations