Beispiel #1
0
        protected void SkipSeparator()
        {
            for (; !IsEof();)
            {
                for (; CharTypes.IsWhitespace(ch); ScanChar())
                {
                    ;
                }

                switch (ch)
                {
                case '#':     // MySQL specified
                    for (; ScanChar() != '\n';)
                    {
                        if (IsEof())
                        {
                            return;
                        }
                    }
                    ScanChar();
                    continue;

                case '/':
                    if (HasChars(2) && '*' == sql[curIndex + 1])
                    {
                        bool commentSkip;
                        if ('!' == sql[curIndex + 2])
                        {
                            ScanChar(3);
                            inCStyleComment       = true;
                            inCStyleCommentIgnore = false;
                            commentSkip           = false;
                            // MySQL use 5 digits to indicate version. 50508 means MySQL 5.5.8
                            if (HasChars(5) &&
                                CharTypes.IsDigit(ch) &&
                                CharTypes.IsDigit(sql[curIndex + 1]) &&
                                CharTypes.IsDigit(sql[curIndex + 2]) &&
                                CharTypes.IsDigit(sql[curIndex + 3]) &&
                                CharTypes.IsDigit(sql[curIndex + 4]))
                            {
                                int version = ch - '0';
                                version *= 10;
                                version += sql[curIndex + 1] - '0';
                                version *= 10;
                                version += sql[curIndex + 2] - '0';
                                version *= 10;
                                version += sql[curIndex + 3] - '0';
                                version *= 10;
                                version += sql[curIndex + 4] - '0';
                                ScanChar(5);
                                if (version > C_STYLE_COMMENT_VERSION)
                                {
                                    inCStyleCommentIgnore = true;
                                }
                            }
                            SkipSeparator();
                        }
                        else
                        {
                            ScanChar(2);
                            commentSkip = true;
                        }

                        if (commentSkip)
                        {
                            for (int state = 0; !IsEof(); ScanChar())
                            {
                                if (state == 0)
                                {
                                    if ('*' == ch)
                                    {
                                        state = 1;
                                    }
                                }
                                else
                                {
                                    if ('/' == ch)
                                    {
                                        ScanChar();
                                        break;
                                    }
                                    else if ('*' != ch)
                                    {
                                        state = 0;
                                    }
                                }
                            }
                            continue;
                        }
                    }
                    return;

                case '-':
                    if (HasChars(3) && '-' == sql[curIndex + 1] && CharTypes.IsWhitespace(sql[curIndex + 2]))
                    {
                        ScanChar(3);
                        for (; !IsEof(); ScanChar())
                        {
                            if ('\n' == ch)
                            {
                                ScanChar();
                                break;
                            }
                        }
                        continue;
                    }
                    break;

                default:
                    return;
                }
            }
        }
Beispiel #2
0
        private MySQLToken NextTokenInternal()
        {
            switch (ch)
            {
            case '0':
                switch (sql[curIndex + 1])
                {
                case 'x':
                    ScanChar(2);
                    ScanHexaDecimal(false);
                    return(token);

                case 'b':
                    ScanChar(2);
                    ScanBitField(false);
                    return(token);
                }

            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
                ScanNumber();
                return(token);

            case '.':
                if (CharTypes.IsDigit(sql[curIndex + 1]))
                {
                    ScanNumber();
                }
                else
                {
                    ScanChar();
                    token = MySQLToken.PUNC_DOT;
                }
                return(token);

            case '\'':
            case '"':
                ScanString();
                return(token);

            case 'n':
            case 'N':
                if (sql[curIndex + 1] == '\'')
                {
                    ScanChar();
                    ScanString();
                    token = MySQLToken.LITERAL_NCHARS;
                    return(token);
                }
                ScanIdentifier();
                return(token);

            case 'x':
            case 'X':
                if (sql[curIndex + 1] == '\'')
                {
                    ScanChar(2);
                    ScanHexaDecimal(true);
                    return(token);
                }
                ScanIdentifier();
                return(token);

            case 'b':
            case 'B':
                if (sql[curIndex + 1] == '\'')
                {
                    ScanChar(2);
                    ScanBitField(true);
                    return(token);
                }
                ScanIdentifier();
                return(token);

            case '@':
                if (sql[curIndex + 1] == '@')
                {
                    ScanSystemVariable();
                    return(token);
                }
                ScanUserVariable();
                return(token);

            case '?':
                ScanChar();
                token = MySQLToken.QUESTION_MARK;
                ++paramIndex;
                return(token);

            case '(':
                ScanChar();
                token = MySQLToken.PUNC_LEFT_PAREN;
                return(token);

            case ')':
                ScanChar();
                token = MySQLToken.PUNC_RIGHT_PAREN;
                return(token);

            case '[':
                ScanChar();
                token = MySQLToken.PUNC_LEFT_BRACKET;
                return(token);

            case ']':
                ScanChar();
                token = MySQLToken.PUNC_RIGHT_BRACKET;
                return(token);

            case '{':
                ScanChar();
                token = MySQLToken.PUNC_LEFT_BRACE;
                return(token);

            case '}':
                ScanChar();
                token = MySQLToken.PUNC_RIGHT_BRACE;
                return(token);

            case ',':
                ScanChar();
                token = MySQLToken.PUNC_COMMA;
                return(token);

            case ';':
                ScanChar();
                token = MySQLToken.PUNC_SEMICOLON;
                return(token);

            case ':':
                if (sql[curIndex + 1] == '=')
                {
                    ScanChar(2);
                    token = MySQLToken.OP_ASSIGN;
                    return(token);
                }
                ScanChar();
                token = MySQLToken.PUNC_COLON;
                return(token);

            case '=':
                ScanChar();
                token = MySQLToken.OP_EQUALS;
                return(token);

            case '~':
                ScanChar();
                token = MySQLToken.OP_TILDE;
                return(token);

            case '*':
                if (inCStyleComment && sql[curIndex + 1] == '/')
                {
                    inCStyleComment       = false;
                    inCStyleCommentIgnore = false;
                    ScanChar(2);
                    token = MySQLToken.PUNC_C_STYLE_COMMENT_END;
                    return(token);
                }
                ScanChar();
                token = MySQLToken.OP_ASTERISK;
                return(token);

            case '-':
                ScanChar();
                token = MySQLToken.OP_MINUS;
                return(token);

            case '+':
                ScanChar();
                token = MySQLToken.OP_PLUS;
                return(token);

            case '^':
                ScanChar();
                token = MySQLToken.OP_CARET;
                return(token);

            case '/':
                ScanChar();
                token = MySQLToken.OP_SLASH;
                return(token);

            case '%':
                ScanChar();
                token = MySQLToken.OP_PERCENT;
                return(token);

            case '&':
                if (sql[curIndex + 1] == '&')
                {
                    ScanChar(2);
                    token = MySQLToken.OP_LOGICAL_AND;
                    return(token);
                }
                ScanChar();
                token = MySQLToken.OP_AMPERSAND;
                return(token);

            case '|':
                if (sql[curIndex + 1] == '|')
                {
                    ScanChar(2);
                    token = MySQLToken.OP_LOGICAL_OR;
                    return(token);
                }
                ScanChar();
                token = MySQLToken.OP_VERTICAL_BAR;
                return(token);

            case '!':
                if (sql[curIndex + 1] == '=')
                {
                    ScanChar(2);
                    token = MySQLToken.OP_NOT_EQUALS;
                    return(token);
                }
                ScanChar();
                token = MySQLToken.OP_EXCLAMATION;
                return(token);

            case '>':
                switch (sql[curIndex + 1])
                {
                case '=':
                    ScanChar(2);
                    token = MySQLToken.OP_GREATER_OR_EQUALS;
                    return(token);

                case '>':
                    ScanChar(2);
                    token = MySQLToken.OP_RIGHT_SHIFT;
                    return(token);

                default:
                    ScanChar();
                    token = MySQLToken.OP_GREATER_THAN;
                    return(token);
                }

            case '<':
                switch (sql[curIndex + 1])
                {
                case '=':
                    if (sql[curIndex + 2] == '>')
                    {
                        ScanChar(3);
                        token = MySQLToken.OP_NULL_SAFE_EQUALS;
                        return(token);
                    }
                    ScanChar(2);
                    token = MySQLToken.OP_LESS_OR_EQUALS;
                    return(token);

                case '>':
                    ScanChar(2);
                    token = MySQLToken.OP_LESS_OR_GREATER;
                    return(token);

                case '<':
                    ScanChar(2);
                    token = MySQLToken.OP_LEFT_SHIFT;
                    return(token);

                default:
                    ScanChar();
                    token = MySQLToken.OP_LESS_THAN;
                    return(token);
                }

            case '`':
                ScanIdentifierWithAccent();
                return(token);

            default:
                if (CharTypes.IsIdentifierChar(ch))
                {
                    ScanIdentifier();
                }
                else if (IsEof())
                {
                    token    = MySQLToken.EOF;
                    curIndex = eofIndex;
                    //tokenPos = curIndex;
                }
                else
                {
                    throw new ArgumentException("unsupported character: " + ch);
                }
                return(token);
            }
        }
Beispiel #3
0
        protected void ScanNumber()
        {
            offsetCache = curIndex;
            sizeCache   = 1;

            bool fstDot = ch == '.';
            bool dot    = fstDot;
            bool 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 = MySQLKeywords.Instance.GetKeyword(stringValueUppercase);
                            token = tok == null ? MySQLToken.IDENTIFIER : tok;
                        }
                        return;
                    }
                    else
                    {
                        throw new ArgumentException("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 = MySQLKeywords.Instance.GetKeyword(stringValueUppercase);
                        token = tok == null ? MySQLToken.IDENTIFIER : tok;
                    }
                    else
                    {
                        throw new ArgumentException("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;
                }
                break;

            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 = MySQLKeywords.Instance.GetKeyword(stringValueUppercase);
                    token = tok == null ? MySQLToken.IDENTIFIER : tok;
                }
                else
                {
                    throw new ArgumentException("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 = MySQLKeywords.Instance.GetKeyword(stringValueUppercase);
                    token = tok == null ? MySQLToken.IDENTIFIER : tok;
                }
                else
                {
                    throw new ArgumentException("expect digit char after SIGN for 'e': " + ch);
                }
                return;
            }
        }