summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibSQL/Parser.h
blob: 953fa9abd27b486dbca6cd0aca1f21e6c710faac (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/*
 * Copyright (c) 2021, Tim Flynn <trflynn89@pm.me>
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#pragma once

#include <AK/String.h>
#include <AK/StringView.h>
#include <LibSQL/AST.h>
#include <LibSQL/Lexer.h>
#include <LibSQL/Token.h>

namespace SQL {

class Parser {
    struct Position {
        size_t line { 0 };
        size_t column { 0 };
    };

    struct Error {
        String message;
        Position position;

        String to_string() const
        {
            return String::formatted("{} (line: {}, column: {})", message, position.line, position.column);
        }
    };

public:
    explicit Parser(Lexer lexer);

    NonnullRefPtr<Statement> next_statement();

    bool has_errors() const { return m_parser_state.m_errors.size(); }
    const Vector<Error>& errors() const { return m_parser_state.m_errors; }

protected:
    NonnullRefPtr<Expression> parse_expression(); // Protected for unit testing.

private:
    struct ParserState {
        explicit ParserState(Lexer);

        Lexer m_lexer;
        Token m_token;
        Vector<Error> m_errors;
    };

    NonnullRefPtr<CreateTable> parse_create_table_statement();
    NonnullRefPtr<DropTable> parse_drop_table_statement();
    NonnullRefPtr<Delete> parse_delete_statement();

    NonnullRefPtr<Expression> parse_primary_expression();
    NonnullRefPtr<Expression> parse_secondary_expression(NonnullRefPtr<Expression> primary);
    bool match_secondary_expression() const;
    Optional<NonnullRefPtr<Expression>> parse_literal_value_expression();
    Optional<NonnullRefPtr<Expression>> parse_column_name_expression();
    Optional<NonnullRefPtr<Expression>> parse_unary_operator_expression();
    Optional<NonnullRefPtr<Expression>> parse_binary_operator_expression(NonnullRefPtr<Expression> lhs);
    Optional<NonnullRefPtr<Expression>> parse_chained_expression();
    Optional<NonnullRefPtr<Expression>> parse_cast_expression();
    Optional<NonnullRefPtr<Expression>> parse_case_expression();
    Optional<NonnullRefPtr<Expression>> parse_collate_expression(NonnullRefPtr<Expression> expression);
    Optional<NonnullRefPtr<Expression>> parse_is_expression(NonnullRefPtr<Expression> expression);
    Optional<NonnullRefPtr<Expression>> parse_match_expression(NonnullRefPtr<Expression> lhs, bool invert_expression);
    Optional<NonnullRefPtr<Expression>> parse_null_expression(NonnullRefPtr<Expression> expression, bool invert_expression);
    Optional<NonnullRefPtr<Expression>> parse_between_expression(NonnullRefPtr<Expression> expression, bool invert_expression);
    Optional<NonnullRefPtr<Expression>> parse_in_expression(NonnullRefPtr<Expression> expression, bool invert_expression);

    NonnullRefPtr<ColumnDefinition> parse_column_definition();
    NonnullRefPtr<TypeName> parse_type_name();
    NonnullRefPtr<SignedNumber> parse_signed_number();
    NonnullRefPtr<CommonTableExpression> parse_common_table_expression();
    NonnullRefPtr<QualifiedTableName> parse_qualified_table_name();
    NonnullRefPtr<ReturningClause> parse_returning_clause();

    Token consume();
    Token consume(TokenType type);
    bool consume_if(TokenType type);
    bool match(TokenType type) const;

    void expected(StringView what);
    void syntax_error(String message);

    Position position() const;

    ParserState m_parser_state;
};

}