From 757114a3c5b748567b42f273c7b78ca039ae983c Mon Sep 17 00:00:00 2001 From: Spartan322 Date: Tue, 28 Nov 2023 05:09:26 -0500 Subject: Add `deps/dryad` -> https://github.com/Spartan322/dryad Add `deps/fmt` -> https://github.com/fmtlib/fmt Add `deps/range-v3` -> https://github.com/ericniebler/range-v3 Improve parser error and warning support Update .clang-format Update `deps/SCsub` --- src/openvic-dataloader/detail/dsl.hpp | 150 ++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 src/openvic-dataloader/detail/dsl.hpp (limited to 'src/openvic-dataloader/detail/dsl.hpp') diff --git a/src/openvic-dataloader/detail/dsl.hpp b/src/openvic-dataloader/detail/dsl.hpp new file mode 100644 index 0000000..9b544bc --- /dev/null +++ b/src/openvic-dataloader/detail/dsl.hpp @@ -0,0 +1,150 @@ +#pragma once + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "detail/StringLiteral.hpp" + +namespace ovdl::dsl { + template + constexpr auto callback(Callback... cb) { + return lexy::bind(lexy::callback(cb...), lexy::parse_state, lexy::values); + } + + template + constexpr auto sink(Sink sink) { + return lexy::bind_sink(sink, lexy::parse_state); + } + + template + constexpr auto collect(Callback callback) { + return sink(lexy::collect(callback)); + } + + template + constexpr auto collect(Callback callback) { + return sink(lexy::collect(callback)); + } + + template + constexpr auto construct = callback( + [](StateType& state, ovdl::NodeLocation loc, auto&& arg) { + if constexpr (std::is_same_v, lexy::nullopt>) + return state.ast().template create(loc); + else + return state.ast().template create(loc, DRYAD_FWD(arg)); + }, + [](StateType& state, ovdl::NodeLocation loc, auto&&... args) { + return state.ast().template create(loc, DRYAD_FWD(args)...); + }); + + template + constexpr auto construct_list = callback( + [](StateType& state, const char* begin, ListType&& arg, const char* end) { + return state.ast().template create(NodeLocation::make_from(begin, end), DRYAD_FWD(arg)); + }, + [](StateType& state, const char* begin, lexy::nullopt, const char* end) { + return state.ast().template create(NodeLocation::make_from(begin, end)); + }, + [](StateType& state, const char* begin, const char* end) { + return state.ast().template create(NodeLocation::make_from(begin, end)); + }); + + template + constexpr auto construct_list = callback( + [](StateType& state, const char* begin, ListType&& arg, const char* end) { + return state.ast().template create(NodeLocation::make_from(begin, end), DRYAD_FWD(arg)); + }, + [](StateType& state, const char* begin, lexy::nullopt, const char* end) { + return state.ast().template create(NodeLocation::make_from(begin, end)); + }); + + template + consteval auto make_range() { + if constexpr (LOW == HIGH) { + return ::lexy::dsl::lit_c; + } else if constexpr (LOW == (HIGH - 1)) { + return ::lexy::dsl::lit_c / ::lexy::dsl::lit_c; + } else { + return ::lexy::dsl::lit_c / make_range(); + } + } + + template + constexpr auto position_brackets = lexy::dsl::brackets(lexy::dsl::position(lexy::dsl::lit_c), lexy::dsl::position(lexy::dsl::lit_c)); + + constexpr auto round_bracketed = position_brackets<'(', ')'>; + constexpr auto square_bracketed = position_brackets<'[', ']'>; + constexpr auto curly_bracketed = position_brackets<'{', '}'>; + constexpr auto angle_bracketed = position_brackets<'<', '>'>; + + template + constexpr auto p = lexy::dsl::position(lexy::dsl::p); + + template + static constexpr auto default_kw_value = dsl::callback( + [](ParseType& state, NodeLocation loc) { + return state.ast().template create(loc, state.ast().intern(Keyword.data(), Keyword.size())); + }); + + template< + IsParseState ParseType, + typename Identifier, + typename RuleValue, + ovdl::detail::string_literal Keyword, + auto Production, + auto Value> + struct keyword_rule { + struct rule_t { + static constexpr auto keyword = ovdl::dsl::keyword(lexy::dsl::inline_); + static constexpr auto rule = lexy::dsl::position(keyword) >> lexy::dsl::equal_sign; + static constexpr auto value = Value; + }; + static constexpr auto rule = dsl::p >> Production; + static constexpr auto value = construct; + }; + + template< + IsParseState ParseType, + typename Identifier, + typename RuleValue, + ovdl::detail::string_literal Keyword, + auto Production, + auto Value> + struct fkeyword_rule : keyword_rule { + using base_type = keyword_rule; + struct context_t; + struct rule_t : base_type::rule_t { + static constexpr auto flag = lexy::dsl::context_flag; + struct too_many_error { + static constexpr auto name = "expected event " + Keyword + " to only be found once"; + }; + static constexpr auto must = lexy::dsl::must(rule_t::flag.is_reset()) + . +// See https://stackoverflow.com/questions/77144003/use-of-template-keyword-before-dependent-template-name +// THANKS FOR NOTHING MICROSOFT, CAN'T EVEN GET THE STANDARD RIGHT +#if !defined(_MSC_VER) || defined(__clang__) + template +#endif + error; + }; + static constexpr auto make_flag = rule_t::flag.create(); + + static constexpr auto rule = dsl::p >> (rule_t::must >> rule_t::flag.set()) >> Production; + static constexpr auto value = construct; + }; + + template + struct rule_helper { + static constexpr auto flags = (Args::make_flag + ...); + static constexpr auto p = (lexy::dsl::p | ...); + }; +} \ No newline at end of file -- cgit v1.2.3-56-ga3b1