Skip to content

Commit

Permalink
feat: enrich sql_parser_element_kind.
Browse files Browse the repository at this point in the history
  • Loading branch information
ashigeru committed Aug 21, 2024
1 parent 78f5c00 commit e887211
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 2 deletions.
55 changes: 53 additions & 2 deletions include/mizugaki/parser/sql_parser_element_kind.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <array>
#include <optional>
#include <ostream>
#include <string>
#include <string_view>
Expand Down Expand Up @@ -64,6 +65,14 @@ enum class sql_parser_element_kind : std::size_t {
string_literal_concatenation,
};

/// @private
/// @brief the first element of sql_parser_element_kind.
constexpr sql_parser_element_kind sql_parser_element_kind_first = sql_parser_element_kind::statement;

/// @private
/// @brief the last element of sql_parser_element_kind.
constexpr sql_parser_element_kind sql_parser_element_kind_last = sql_parser_element_kind::string_literal_concatenation;

/**
* @brief represents an associated list of sql_parser_element_map.
* @tparam V the value type
Expand Down Expand Up @@ -114,10 +123,10 @@ class sql_parser_element_map {
}

private:
static constexpr std::size_t offset = static_cast<std::size_t>(key_type::statement);
static constexpr std::size_t offset = static_cast<std::size_t>(sql_parser_element_kind_first);

static constexpr std::size_t capacity =
static_cast<std::size_t>(key_type::string_literal_concatenation) + 1ULL - offset;
static_cast<std::size_t>(sql_parser_element_kind_last) + 1ULL - offset;

std::array<V, capacity> entries_ {};
};
Expand Down Expand Up @@ -152,6 +161,25 @@ inline constexpr std::string_view to_string_view(sql_parser_element_kind value)
std::abort();
}

/**
* @brief returns the kind corresponding to the given name.
* @param name the enum constant name
* @return the corresponded enum constant
* @return empty if there is no such the entry
*/
inline constexpr std::optional<sql_parser_element_kind> find_sql_parser_element_kind(std::string_view name) noexcept {
using kind_type = sql_parser_element_kind;
for (auto value = static_cast<std::size_t>(sql_parser_element_kind_first);
value <= static_cast<std::size_t>(sql_parser_element_kind_last);
++value) {
auto kind = static_cast<kind_type>(value);
if (to_string_view(kind) == name) {
return kind;
}
}
return std::nullopt;
}

/**
* @brief appends string representation of the given value.
* @param out the target output
Expand All @@ -162,4 +190,27 @@ inline std::ostream& operator<<(std::ostream& out, sql_parser_element_kind value
return out << to_string_view(value);
}

/**
* @brief appends string representation of the given value.
* @param out the target output
* @param value the target value
* @return the output
*/
template<class V>
inline std::ostream& operator<<(std::ostream& out, sql_parser_element_map<V> const& value) {
out << "{";
using kind_type = sql_parser_element_kind;
for (auto index = static_cast<std::size_t>(sql_parser_element_kind_first);
index <= static_cast<std::size_t>(sql_parser_element_kind_last);
++index) {
auto kind = static_cast<kind_type>(index);
if (kind != sql_parser_element_kind_first) {
out << ", ";
}
out << to_string_view(kind) << ":" << value[kind];
}
out << "}";
return out;
}

} // namespace mizugaki::parser
1 change: 1 addition & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ add_test_executable(mizugaki/ast/query_dispatch_test.cpp)
add_test_executable(mizugaki/ast/statement_dispatch_test.cpp)

# SQL parser
add_test_executable(mizugaki/parser/sql_parser_element_kind_test.cpp)
add_test_executable(mizugaki/parser/sql_parser_statement_test.cpp)
add_test_executable(mizugaki/parser/sql_parser_query_test.cpp)
add_test_executable(mizugaki/parser/sql_parser_table_test.cpp)
Expand Down
41 changes: 41 additions & 0 deletions test/mizugaki/parser/sql_parser_element_kind_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#include <mizugaki/parser/sql_parser_element_kind.h>

#include <gtest/gtest.h>

namespace mizugaki::parser {

class sql_parser_element_kind_test : public ::testing::Test {};

using kind_type = sql_parser_element_kind;

TEST_F(sql_parser_element_kind_test, map) {
sql_parser_element_map<int> map {};
EXPECT_EQ(map.get<kind_type::statement>(), 0);

map.get<kind_type::statement>() = 100;
EXPECT_EQ(map[kind_type::statement], 100);

sql_parser_element_map<int> const& cmap = map;
map.get<kind_type::string_literal_concatenation>() = 100;
EXPECT_EQ(cmap[kind_type::string_literal_concatenation], 100);
}

TEST_F(sql_parser_element_kind_test, find) {
EXPECT_EQ(find_sql_parser_element_kind("statement"), kind_type::statement);
EXPECT_EQ(find_sql_parser_element_kind("string_literal_concatenation"), kind_type::string_literal_concatenation);
EXPECT_EQ(find_sql_parser_element_kind("select_element"), kind_type::select_element);
EXPECT_EQ(find_sql_parser_element_kind("MISSING"), std::nullopt);
}

TEST_F(sql_parser_element_kind_test, output) {
sql_parser_element_map<int> map {};
for (auto index = static_cast<std::size_t>(sql_parser_element_kind_first);
index <= static_cast<std::size_t>(sql_parser_element_kind_last);
++index) {
auto kind = static_cast<kind_type>(index);
map[kind] = index + 1;
}
std::cout << map << std::endl;
}

} // namespace mizugaki::parser

0 comments on commit e887211

Please sign in to comment.