internal Tokens Scan()
{
char ch;
char[] text = _text;
_token = Tokens.None;
while (true)
{
loop:
_start = _pos;
_op = Operators.Noop;
ch = text[_pos++];
switch (ch)
{
case (char)0:
_token = Tokens.EOS;
goto end_loop;
case ' ':
case '\t':
case '\n':
case '\r':
ScanWhite();
goto loop;
case '(':
_token = Tokens.LeftParen;
goto end_loop;
case ')':
_token = Tokens.RightParen;
goto end_loop;
case '#':
ScanDate();
CheckToken(Tokens.Date);
goto end_loop;
case '\'':
ScanString('\'');
CheckToken(Tokens.StringConst);
goto end_loop;
case '=':
_token = Tokens.BinaryOp;
_op = Operators.EqualTo;
goto end_loop;
case '>':
_token = Tokens.BinaryOp;
ScanWhite();
if (text[_pos] == '=')
{
_pos++;
_op = Operators.GreaterOrEqual;
}
else
_op = Operators.GreaterThen;
goto end_loop;
case '<':
_token = Tokens.BinaryOp;
ScanWhite();
if (text[_pos] == '=')
{
_pos++;
_op = Operators.LessOrEqual;
}
else if (text[_pos] == '>')
{
_pos++;
_op = Operators.NotEqual;
}
else
_op = Operators.LessThen;
goto end_loop;
case '+':
_token = Tokens.BinaryOp;
_op = Operators.Plus;
goto end_loop;
case '-':
_token = Tokens.BinaryOp;
_op = Operators.Minus;
goto end_loop;
case '*':
_token = Tokens.BinaryOp;
_op = Operators.Multiply;
goto end_loop;
case '/':
_token = Tokens.BinaryOp;
_op = Operators.Divide;
goto end_loop;
case '%':
_token = Tokens.BinaryOp;
_op = Operators.Modulo;
goto end_loop;
/* Beginning of bitwise operators */
case '&':
_token = Tokens.BinaryOp;
_op = Operators.BitwiseAnd;
goto end_loop;
case '|':
_token = Tokens.BinaryOp;
_op = Operators.BitwiseOr;
goto end_loop;
case '^':
_token = Tokens.BinaryOp;
_op = Operators.BitwiseXor;
goto end_loop;
case '~':
_token = Tokens.BinaryOp;
_op = Operators.BitwiseNot;
goto end_loop;
/* we have bracketed identifier */
case '[':
// BUG: special case
ScanName(']', _escape, "]\\");
CheckToken(Tokens.Name);
goto end_loop;
case '`':
ScanName('`', '`', "`");
CheckToken(Tokens.Name);
goto end_loop;
default:
/* Check for list separator */
if (ch == _listSeparator)
{
_token = Tokens.ListSeparator;
goto end_loop;
}
if (ch == '.')
{
if (_prevOperand == Empty)
{
ScanNumeric();
}
else
{
_token = Tokens.Dot;
}
goto end_loop;
}
/* Check for binary constant */
if (ch == '0' && (text[_pos] == 'x' || text[_pos] == 'X'))
{
ScanBinaryConstant();
_token = Tokens.BinaryConst;
goto end_loop;
}
/* Check for number: digit is always good; . or - only if osNil. */
if (IsDigit(ch))
{
ScanNumeric();
goto end_loop;
}
/* Check for reserved word */
ScanReserved();
if (_token != Tokens.None)
{
goto end_loop;
}
/* Alpha means identifier */
if (IsAlphaNumeric(ch))
{
ScanName();
if (_token != Tokens.None)
{
CheckToken(Tokens.Name);
goto end_loop;
}
}
/* Don't understand that banter at all. */
_token = Tokens.Unknown;
throw ExprException.UnknownToken(new string(text, _start, _pos - _start), _start + 1);
}
}
end_loop:
return _token;
}