in HSQL/src/org/hsqldb1/Tokenizer.java [740:1118]
private void getToken() throws HsqlException {
if (bWait) {
bWait = false;
iIndex = nextTokenIndex;
return;
}
if (!retainFirst) {
sLongNameFirst = null;
indexLongNameFirst = -1;
typeLongNameFirst = NO_TYPE;
}
while (iIndex < iLength
&& Character.isWhitespace(sCommand.charAt(iIndex))) {
iIndex++;
}
sToken = "";
tokenIndex = iIndex;
if (iIndex >= iLength) {
iType = NO_TYPE;
return;
}
char c = sCommand.charAt(iIndex);
boolean point = false,
digit = false,
exp = false,
afterexp = false;
boolean end = false;
char cfirst = 0;
lastTokenQuotedID = false;
if (Character.isJavaIdentifierStart(c)) {
iType = NAME;
} else if (Character.isDigit(c)) {
iType = NUMBER;
digit = true;
} else {
switch (c) {
case '(' :
sToken = Token.T_OPENBRACKET;
iType = SPECIAL;
iIndex++;
return;
case ')' :
sToken = Token.T_CLOSEBRACKET;
iType = SPECIAL;
iIndex++;
return;
case ',' :
sToken = Token.T_COMMA;
iType = SPECIAL;
iIndex++;
return;
case '*' :
sToken = Token.T_MULTIPLY;
iType = SPECIAL;
iIndex++;
return;
case '=' :
sToken = Token.T_EQUALS;
iType = SPECIAL;
iIndex++;
return;
case ';' :
sToken = Token.T_SEMICOLON;
iType = SPECIAL;
iIndex++;
return;
case '+' :
sToken = Token.T_PLUS;
iType = SPECIAL;
iIndex++;
return;
case '%' :
sToken = Token.T_PERCENT;
iType = SPECIAL;
iIndex++;
return;
case '?' :
sToken = Token.T_QUESTION;
iType = SPECIAL;
iIndex++;
return;
case ':' :
Trace.check(++iIndex < iLength,
Trace.UNEXPECTED_END_OF_COMMAND);
c = sCommand.charAt(iIndex);
Trace.check(Character.isJavaIdentifierStart(c),
Trace.INVALID_IDENTIFIER, ":" + c);
iType = NAMED_PARAM;
break;
case '\"' :
lastTokenQuotedID = true;
iType = QUOTED_IDENTIFIER;
iIndex++;
sToken = getString('"');
if (iIndex == sCommand.length()) {
return;
}
c = sCommand.charAt(iIndex);
if (c == '.') {
sLongNameFirst = sToken;
indexLongNameFirst = tokenIndex;
typeLongNameFirst = iType;
iIndex++;
if (retainFirst) {
throw Trace.error(Trace.THREE_PART_IDENTIFIER);
}
// fredt - todo - avoid recursion - this has problems when there is whitespace
// after the dot - the same with NAME
retainFirst = true;
getToken();
retainFirst = false;
iType = LONG_NAME;
}
return;
case '\'' :
iType = STRING;
iIndex++;
sToken = getString('\'');
return;
case '!' :
case '<' :
case '>' :
case '|' :
case '/' :
case '-' :
cfirst = c;
iType = SPECIAL;
break;
case '.' :
iType = DECIMAL;
point = true;
break;
default :
throw Trace.error(Trace.UNEXPECTED_TOKEN,
String.valueOf(c));
}
}
int start = iIndex++;
while (true) {
if (iIndex >= iLength) {
c = ' ';
end = true;
Trace.check(iType != STRING && iType != QUOTED_IDENTIFIER,
Trace.UNEXPECTED_END_OF_COMMAND);
} else {
c = sCommand.charAt(iIndex);
}
switch (iType) {
case NAMED_PARAM :
case NAME :
if (Character.isJavaIdentifierPart(c)) {
break;
}
// fredt - todo new char[] to back sToken
sToken =
sCommand.substring(start,
iIndex).toUpperCase(Locale.ENGLISH);
// the following only for NAME, not for NAMED_PARAM
if (iType == NAMED_PARAM) {
return;
}
if (c == '.') {
typeLongNameFirst = iType;
sLongNameFirst = sToken;
indexLongNameFirst = tokenIndex;
iIndex++;
if (retainFirst) {
throw Trace.error(Trace.THREE_PART_IDENTIFIER);
}
retainFirst = true;
getToken(); // todo: eliminate recursion
retainFirst = false;
iType = LONG_NAME;
} else if (c == '(') {
// it is a function call
} else {
// if in value list then it is a value
int type = valueTokens.get(sToken, -1);
if (type != -1) {
iType = type;
}
}
return;
case QUOTED_IDENTIFIER :
case STRING :
// shouldn't get here
break;
case REMARK :
if (end) {
// unfinished remark
// maybe print error here
iType = NO_TYPE;
return;
} else if (c == '*') {
iIndex++;
if (iIndex < iLength
&& sCommand.charAt(iIndex) == '/') {
// using recursion here
iIndex++;
getToken();
return;
}
}
break;
case REMARK_LINE :
if (end) {
iType = NO_TYPE;
return;
} else if (c == '\r' || c == '\n') {
// using recursion here
getToken();
return;
}
break;
case SPECIAL :
if (c == '/' && cfirst == '/') {
iType = REMARK_LINE;
break;
} else if (c == '-' && cfirst == '-') {
iType = REMARK_LINE;
break;
} else if (c == '*' && cfirst == '/') {
iType = REMARK;
break;
} else if (c == '>' || c == '=' || c == '|') {
break;
}
sToken = sCommand.substring(start, iIndex);
return;
case NUMBER :
case FLOAT :
case DECIMAL :
if (Character.isDigit(c)) {
digit = true;
} else if (c == '.') {
iType = DECIMAL;
if (point) {
throw Trace.error(Trace.UNEXPECTED_TOKEN, ".");
}
point = true;
} else if (c == 'E' || c == 'e') {
if (exp) {
throw Trace.error(Trace.UNEXPECTED_TOKEN, "E");
}
// HJB-2001-08-2001 - now we are sure it's a float
iType = FLOAT;
// first character after exp may be + or -
afterexp = true;
point = true;
exp = true;
} else if (c == '-' && afterexp) {
afterexp = false;
} else if (c == '+' && afterexp) {
afterexp = false;
} else {
afterexp = false;
if (!digit) {
if (point && start == iIndex - 1) {
sToken = ".";
iType = SPECIAL;
return;
}
throw Trace.error(Trace.UNEXPECTED_TOKEN,
String.valueOf(c));
}
sToken = sCommand.substring(start, iIndex);
return;
}
}
iIndex++;
}
}