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); }
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); }
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); }
private static bool IsReservedKeyword(string sql, RawToken token) { foreach (var keyword in Keywords.Reserved) { if (TryMatchKeyword(sql, token, keyword)) { return(true); } } return(false); }
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); }
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); }
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); }
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); }
public SqlLiteral(string sql, RawToken token) : base(sql, ImmutableArray <SqlNode> .Empty) { this.Token = token.WithParent(this); }
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); }
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); }
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); }
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()); }
public QuotedIdentifier(string sql, RawToken identifier) : base(sql, ImmutableArray <SqlNode> .Empty) { this.Identifier = identifier.WithParent(this); }