Пример #1
0
            internal static bool TryParseIdentifier(string sql, int position, out RawToken token)
            {
                if (char.IsLetter(sql[position]))
                {
                    var start = position;
                    position++;
                    while (sql.TryElementAt(position, out var next) &&
                           (char.IsLetterOrDigit(next) || next == '_'))
                    {
                        position++;
                    }

                    token = new RawToken(SqlKind.Identifier, start, position);
                    return(true);
                }

                if (sql.TryElementAt(position, out var c) &&
                    c == '"')
                {
                    var start = position;
                    position++;
                    token = SkipNext(sql, '"', ref position)
                        ? new RawToken(SqlKind.QuotedIdentifier, start, position)
                        : new RawToken(SqlKind.QuotedIdentifier, start, sql.Length);

                    return(true);
                }

                token = default;
                return(false);
            }
Пример #2
0
            internal static bool TryParseNumber(string sql, int position, out RawToken token)
            {
                if (char.IsDigit(sql[position]))
                {
                    var start = position;
                    position++;
                    while (sql.TryElementAt(position, out var next) &&
                           char.IsDigit(next))
                    {
                        position++;
                    }

                    if (sql.TryElementAt(position, out var c) &&
                        c == '.')
                    {
                        position++;
                        while (sql.TryElementAt(position, out var next) &&
                               char.IsDigit(next))
                        {
                            position++;
                        }

                        token = new RawToken(SqlKind.Float, start, position);
                    }
                    else
                    {
                        token = new RawToken(SqlKind.Integer, start, position);
                    }

                    return(true);
                }

                token = default;
                return(false);
            }
Пример #3
0
            internal static bool TryParse(string sql, int position, string expected, SqlKind kind, out RawToken token)
            {
                if (TryMatch(sql, position, expected))
                {
                    token = new RawToken(kind, position, position + expected.Length);
                    return(true);
                }

                token = default;
                return(false);
            }
Пример #4
0
        private static bool IsReservedKeyword(string sql, RawToken token)
        {
            foreach (var keyword in Keywords.Reserved)
            {
                if (TryMatchKeyword(sql, token, keyword))
                {
                    return(true);
                }
            }

            return(false);
        }
Пример #5
0
            internal static bool TryParse(string sql, int position, char expected, SqlKind kind, out RawToken token)
            {
                if (sql.TryElementAt(position, out var c) &&
                    c == expected)
                {
                    token = RawToken.SingleChar(kind, position);
                    return(true);
                }

                token = default;
                return(false);
            }
Пример #6
0
        private static bool TryMatchKeyword(string sql, RawToken token, string keyword)
        {
            if (token.Kind == SqlKind.Identifier &&
                token.Length == keyword.Length)
            {
                for (int i = 0; i < token.Length; i++)
                {
                    if (char.ToUpper(sql[token.Start + i]) != keyword[i])
                    {
                        return(false);
                    }
                }

                return(true);
            }

            return(false);
        }
Пример #7
0
            internal static bool TryParseComment(string sql, int position, out RawToken token)
            {
                if (TryMatch(sql, position, "--"))
                {
                    var start = position;
                    position += 2;
                    if (SkipNext(sql, '\n', ref position) ||
                        position == sql.Length)
                    {
                        var end = position;
                        if (sql[position - 2] == '\r')
                        {
                            end -= 2;
                        }
                        else if (sql[position - 1] == '\n')
                        {
                            end -= 1;
                        }

                        token = new RawToken(SqlKind.SingleLineCommentTrivia, start, end);
                    }
                    else
                    {
                        token = new RawToken(SqlKind.SingleLineCommentTrivia, start, sql.Length);
                    }

                    return(true);
                }

                if (TryMatch(sql, position, "/*"))
                {
                    var start = position;
                    position += 2;
                    token     = SkipNext(sql, "*/", ref position)
                        ? new RawToken(SqlKind.MultiLineCommentTrivia, start, position)
                        : new RawToken(SqlKind.MultiLineCommentTrivia, start, sql.Length);

                    return(true);
                }

                token = default;
                return(false);
            }
Пример #8
0
            internal static bool TryParseString(string sql, int position, out RawToken token)
            {
                if (sql[position] == '\'')
                {
                    var start = position;
                    position++;
                    if (SkipNext(sql, '\'', ref position))
                    {
                        token = new RawToken(SqlKind.String, start, position);
                    }
                    else
                    {
                        token = new RawToken(SqlKind.String, start, sql.Length);
                    }

                    return(true);
                }

                token = default;
                return(false);
            }
Пример #9
0
 public SqlLiteral(string sql, RawToken token)
     : base(sql, ImmutableArray <SqlNode> .Empty)
 {
     this.Token = token.WithParent(this);
 }
Пример #10
0
        private static bool TryMatchKeyword(string sql, ImmutableArray <RawToken> tokens, int position, string keyword, out RawToken token)
        {
            if (TryMatch(tokens, position, SqlKind.Identifier, out token) &&
                TryMatchKeyword(sql, token, keyword))
            {
                return(true);
            }

            token = default;
            return(false);
        }
Пример #11
0
        private static bool TryMatch(ImmutableArray <RawToken> tokens, int position, SqlKind kind, out RawToken token)
        {
            if (tokens.TryElementAt(position, out token) &&
                token.Kind == kind)
            {
                return(true);
            }

            token = default;
            return(false);
        }
Пример #12
0
        private static bool TryAs(string sql, ImmutableArray <RawToken> tokens, ref int position, out RawToken @as, out SqlSimpleName name)
        {
            name = null;
            if (TryMatchKeyword(sql, tokens, position, "AS", out @as))
            {
                position++;
                if (SqlSimpleName(sql, tokens, ref position, allowKeyword: true) is SqlSimpleName simpleName)
                {
                    name = simpleName;
                }

                return(true);
            }

            return(false);
        }
Пример #13
0
        public static ImmutableArray <RawToken> Tokens(string sql)
        {
            if (string.IsNullOrEmpty(sql))
            {
                return(ImmutableArray <RawToken> .Empty);
            }

            var tokens   = new List <RawToken>();
            var position = 0;

            while (position < sql.Length)
            {
                TokenParser.SkipWhitespace(sql, ref position);
                if (TokenParser.TryParseNumber(sql, position, out var token) ||
                    TokenParser.TryParseString(sql, position, out token) ||
                    TokenParser.TryParseComment(sql, position, out token) ||
                    TokenParser.TryParseIdentifier(sql, position, out token) ||
                    TokenParser.TryParse(sql, position, "<>", SqlKind.NotEqualsToken, out token) ||
                    TokenParser.TryParse(sql, position, "<=", SqlKind.LessThanEqualsToken, out token) ||
                    TokenParser.TryParse(sql, position, ">=", SqlKind.GreaterThanEqualsToken, out token) ||
                    TokenParser.TryParse(sql, position, "|/", SqlKind.SquareRootToken, out token) ||
                    TokenParser.TryParse(sql, position, "||/", SqlKind.CubeRootToken, out token) ||
                    TokenParser.TryParse(sql, position, "!!", SqlKind.ExclamationExclamationToken, out token) ||
                    TokenParser.TryParse(sql, position, "<<", SqlKind.LessThanLessThanToken, out token) ||
                    TokenParser.TryParse(sql, position, ">>", SqlKind.GreaterThanGreaterThanToken, out token) ||
                    TokenParser.TryParse(sql, position, '+', SqlKind.PlusToken, out token) ||
                    TokenParser.TryParse(sql, position, '-', SqlKind.MinusToken, out token) ||
                    TokenParser.TryParse(sql, position, '*', SqlKind.AsteriskToken, out token) ||
                    TokenParser.TryParse(sql, position, '/', SqlKind.SlashToken, out token) ||
                    TokenParser.TryParse(sql, position, '^', SqlKind.ExponentToken, out token) ||
                    TokenParser.TryParse(sql, position, '%', SqlKind.PercentToken, out token) ||
                    TokenParser.TryParse(sql, position, '@', SqlKind.AtToken, out token) ||
                    TokenParser.TryParse(sql, position, '!', SqlKind.ExclamationToken, out token) ||
                    TokenParser.TryParse(sql, position, '&', SqlKind.AmpersandToken, out token) ||
                    TokenParser.TryParse(sql, position, '|', SqlKind.BarToken, out token) ||
                    TokenParser.TryParse(sql, position, '#', SqlKind.HashToken, out token) ||
                    TokenParser.TryParse(sql, position, '~', SqlKind.TildeToken, out token) ||
                    TokenParser.TryParse(sql, position, '=', SqlKind.EqualsToken, out token) ||
                    TokenParser.TryParse(sql, position, '<', SqlKind.LessThanEqualsToken, out token) ||
                    TokenParser.TryParse(sql, position, '>', SqlKind.GreaterThanToken, out token) ||
                    TokenParser.TryParse(sql, position, '(', SqlKind.OpenParenToken, out token) ||
                    TokenParser.TryParse(sql, position, ')', SqlKind.CloseParenToken, out token) ||
                    TokenParser.TryParse(sql, position, '[', SqlKind.OpenBracketToken, out token) ||
                    TokenParser.TryParse(sql, position, ']', SqlKind.CloseBracketToken, out token) ||
                    TokenParser.TryParse(sql, position, '.', SqlKind.DotToken, out token) ||
                    TokenParser.TryParse(sql, position, ',', SqlKind.CommaToken, out token) ||
                    TokenParser.TryParse(sql, position, ';', SqlKind.SemicolonToken, out token) ||
                    TokenParser.TryParse(sql, position, ':', SqlKind.ColonToken, out token))
                {
                    position = token.End;
                    tokens.Add(token);
                }
                else
                {
                    tokens.Add(RawToken.SingleChar(SqlKind.Unknown, position));
                    position++;
                }
            }

            return(tokens.ToImmutableArray());
        }
Пример #14
0
 public QuotedIdentifier(string sql, RawToken identifier)
     : base(sql, ImmutableArray <SqlNode> .Empty)
 {
     this.Identifier = identifier.WithParent(this);
 }