-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: introduce limits for repeated elements in grammar.
- Loading branch information
Showing
12 changed files
with
833 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
#pragma once | ||
|
||
#include <array> | ||
#include <ostream> | ||
#include <string> | ||
#include <string_view> | ||
#include <type_traits> | ||
|
||
namespace mizugaki::parser { | ||
|
||
/** | ||
* @brief represents syntactic element kind of SQL. | ||
*/ | ||
enum class sql_parser_element_kind : std::size_t { | ||
/// @brief statements in compilation units. | ||
statement = 0, | ||
|
||
/// @brief elements in schema declarations. | ||
schema_element_definition, | ||
|
||
/// @brief elements in table declarations. | ||
table_element_definition, | ||
|
||
/// @brief constraint definitions in column declarations. | ||
column_constraint_definition, | ||
|
||
/// @brief column references in foreign key columns, join correlations, etc. | ||
column_reference, | ||
|
||
/// @brief storage parameters in table or index definitions. | ||
storage_parameter, | ||
|
||
/// @brief set clauses in `UPDATE` statement. | ||
set_clause, | ||
|
||
/// @brief `WITH` elements in `SELECT` statement. | ||
with_element, | ||
|
||
/// @brief elements in `SELECT` statement. | ||
select_element, | ||
|
||
/// @brief table references in `FROM` clause. | ||
table_reference, | ||
|
||
/// @brief column references in `GROUP BY` clause. | ||
grouping_element, | ||
|
||
/// @brief column references in `ORDER BY` clause. | ||
ordering_element, | ||
|
||
/// @brief field definitions in row type. | ||
field_definition, | ||
|
||
/// @brief expressions in table value constructor (e.g., `VALUES ...`). | ||
row_expression, | ||
|
||
/// @brief elements in expression list. | ||
scalar_expression, | ||
|
||
/// @brief elements in `CASE` expression. | ||
when_clause, | ||
|
||
/// @brief elements in string literal concatenations. | ||
string_literal_concatenation, | ||
}; | ||
|
||
/** | ||
* @brief represents an associated list of sql_parser_element_map. | ||
* @tparam V the value type | ||
*/ | ||
template<class V> | ||
class sql_parser_element_map { | ||
public: | ||
/// @brief the key type. | ||
using key_type = sql_parser_element_kind; | ||
|
||
/// @brief the value type. | ||
using value_type = V; | ||
|
||
/// @brief the reference type. | ||
using reference = std::add_lvalue_reference_t<value_type>; | ||
|
||
/// @brief the const reference type. | ||
using const_reference = std::add_lvalue_reference_t<std::add_const_t<value_type>>; | ||
|
||
/** | ||
* @brief returns the value corresponding to the given kind. | ||
* @tparam K the target kind | ||
* @return the value | ||
*/ | ||
template<key_type K> | ||
[[nodiscard]] constexpr reference get() noexcept { | ||
return entries_[static_cast<std::size_t>(K) - offset]; | ||
} | ||
|
||
/// @copydoc get() | ||
template<key_type K> | ||
[[nodiscard]] constexpr const_reference get() const noexcept { | ||
return entries_[static_cast<std::size_t>(K) - offset]; | ||
} | ||
|
||
/** | ||
* @brief returns the value corresponding to the given kind. | ||
* @param kind the target kind | ||
* @return the value | ||
*/ | ||
[[nodiscard]] constexpr reference operator[](key_type kind) noexcept { | ||
return entries_[static_cast<std::size_t>(kind) - offset]; | ||
} | ||
|
||
/// @copydoc operator[]() | ||
[[nodiscard]] constexpr const_reference operator[](key_type kind) const noexcept { | ||
return entries_[static_cast<std::size_t>(kind) - offset]; | ||
} | ||
|
||
private: | ||
static constexpr std::size_t offset = static_cast<std::size_t>(key_type::statement); | ||
|
||
static constexpr std::size_t capacity = | ||
static_cast<std::size_t>(key_type::string_literal_concatenation) + 1ULL - offset; | ||
|
||
std::array<V, capacity> entries_ {}; | ||
}; | ||
|
||
/** | ||
* @brief returns string representation of the value. | ||
* @param value the target value | ||
* @return the corresponded string representation | ||
*/ | ||
inline constexpr std::string_view to_string_view(sql_parser_element_kind value) noexcept { | ||
using namespace std::string_view_literals; | ||
using kind = sql_parser_element_kind; | ||
switch (value) { | ||
case kind::statement: return "statement"sv; | ||
case kind::schema_element_definition: return "schema_element_definition"sv; | ||
case kind::table_element_definition: return "table_element_definition"sv; | ||
case kind::column_constraint_definition: return "column_constraint_definition"sv; | ||
case kind::column_reference: return "column_reference"sv; | ||
case kind::storage_parameter: return "storage_parameter"sv; | ||
case kind::set_clause: return "set_clause"sv; | ||
case kind::with_element: return "with_element"sv; | ||
case kind::select_element: return "select_element"sv; | ||
case kind::table_reference: return "table_reference"sv; | ||
case kind::grouping_element: return "grouping_element"sv; | ||
case kind::ordering_element: return "ordering_element"sv; | ||
case kind::field_definition: return "field_definition"sv; | ||
case kind::row_expression: return "row_expression"sv; | ||
case kind::scalar_expression: return "scalar_expression"sv; | ||
case kind::when_clause: return "when_clause"sv; | ||
case kind::string_literal_concatenation: return "string_literal_concatenation"sv; | ||
} | ||
std::abort(); | ||
} | ||
|
||
/** | ||
* @brief appends string representation of the given value. | ||
* @param out the target output | ||
* @param value the target value | ||
* @return the output | ||
*/ | ||
inline std::ostream& operator<<(std::ostream& out, sql_parser_element_kind value) { | ||
return out << to_string_view(value); | ||
} | ||
|
||
} // namespace mizugaki::parser |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
#pragma once | ||
|
||
#include <memory> | ||
#include <utility> | ||
|
||
#include <mizugaki/parser/sql_parser_element_kind.h> | ||
|
||
namespace mizugaki::parser { | ||
|
||
class sql_parser_options { | ||
public: | ||
/// @brief the size type. | ||
using size_type = std::size_t; | ||
|
||
/// @brief default number of next token candidates to display on error. | ||
static constexpr std::size_t default_max_expected_candidates = 5; | ||
|
||
/** | ||
* @brief creates a new instance. | ||
*/ | ||
sql_parser_options(); | ||
|
||
/** | ||
* @brief sets the max number of next token candidates to display on error. | ||
* @param count the max number of candidates, or 0 to disable to display | ||
* @see default_max_expected_candidates | ||
*/ | ||
[[nodiscard]] size_type& max_expected_candidates() noexcept; | ||
|
||
/// @copydoc max_expected_candidates() | ||
[[nodiscard]] size_type const& max_expected_candidates() const noexcept; | ||
|
||
/** | ||
* @brief returns limits of each syntactic element. | ||
* @details the limits are used to restrict the number of elements in the AST. | ||
* Each default limit is 0, which means no limit. | ||
* @return the map of limit sof each syntactic element | ||
*/ | ||
[[nodiscard]] sql_parser_element_map<size_type>& element_limits() noexcept; | ||
|
||
/// @copydoc element_limits() | ||
[[nodiscard]] sql_parser_element_map<size_type> const& element_limits() const noexcept; | ||
|
||
/** | ||
* @brief returns the debug level. | ||
* @return the debug level | ||
* @note this feature is only available for debug configurations | ||
*/ | ||
[[nodiscard]] int& debug() noexcept; | ||
|
||
/// @copydoc debug() | ||
[[nodiscard]] int const& debug() const noexcept; | ||
|
||
private: | ||
int debug_ {}; | ||
size_type max_expected_candidates_ { default_max_expected_candidates }; | ||
std::unique_ptr<sql_parser_element_map<size_type>> element_limits_; | ||
}; | ||
|
||
} // namespace mizugaki::parser |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.