From 7440a5d1433eec4bf87e3723022db187e7f61b1a Mon Sep 17 00:00:00 2001 From: Spartan322 Date: Fri, 28 Jul 2023 00:52:00 -0400 Subject: Rework Grammar and Parser Add proper headless binary construction: Includes basic validation Add Error and Warning structs to Parser Add FileNode pointer getter to Parser Change all `char8_t*` and `const char8_t` to `const char*` in Parser Add Parser move operators and Parser deconstructor Add BufferHandler PIMPL object to Parser Add UTF-8 file Warning to v2script Add proper Grammar value retrieval Add AbstractSyntaxTree for v2script data parser: Has compile-time embedded type information accessible at compile-time and runtime Has Tab-based print functionality Fix wrong environment reference for headless construction in SConstruct Add error retrieval Add BasicCallbackOStreamBuffer for callback streaming Add CallbackStreamBuffer for char Add CallbackWStreamBuffer for wchar_t Add BasicCallbackStream Add CallbackStream for char Add CallbackWStream for wchar_t Add grammar for events and decisions Add event_parse to Parser Add decision_parse to Parser Add .clang-format Ignore dirty lexy module Add CSV parser and grammar: Creates std::vector for a list of lines Add BasicParser and BasicBufferHandler to reduce code reduplication --- include/openvic-dataloader/detail/BasicParser.hpp | 37 ++++++++ .../openvic-dataloader/detail/CallbackOStream.hpp | 100 +++++++++++++++++++++ include/openvic-dataloader/detail/Concepts.hpp | 22 +++++ include/openvic-dataloader/detail/SelfType.hpp | 28 ++++++ include/openvic-dataloader/detail/TypeName.hpp | 52 +++++++++++ 5 files changed, 239 insertions(+) create mode 100644 include/openvic-dataloader/detail/BasicParser.hpp create mode 100644 include/openvic-dataloader/detail/CallbackOStream.hpp create mode 100644 include/openvic-dataloader/detail/Concepts.hpp create mode 100644 include/openvic-dataloader/detail/SelfType.hpp create mode 100644 include/openvic-dataloader/detail/TypeName.hpp (limited to 'include/openvic-dataloader/detail') diff --git a/include/openvic-dataloader/detail/BasicParser.hpp b/include/openvic-dataloader/detail/BasicParser.hpp new file mode 100644 index 0000000..5493804 --- /dev/null +++ b/include/openvic-dataloader/detail/BasicParser.hpp @@ -0,0 +1,37 @@ +#pragma once + +#include +#include +#include +#include + +#include +#include +#include + +namespace ovdl::detail { + class BasicParser { + public: + BasicParser(); + + void set_error_log_to_null(); + void set_error_log_to_stderr(); + void set_error_log_to_stdout(); + void set_error_log_to(std::basic_ostream& stream); + + bool has_error() const; + bool has_fatal_error() const; + bool has_warning() const; + + const std::vector& get_errors() const; + const std::vector& get_warnings() const; + + protected: + std::vector _errors; + std::vector _warnings; + + std::reference_wrapper _error_stream; + const char* _file_path; + bool _has_fatal_error = false; + }; +} \ No newline at end of file diff --git a/include/openvic-dataloader/detail/CallbackOStream.hpp b/include/openvic-dataloader/detail/CallbackOStream.hpp new file mode 100644 index 0000000..641d53f --- /dev/null +++ b/include/openvic-dataloader/detail/CallbackOStream.hpp @@ -0,0 +1,100 @@ +#pragma once + +#include +#include +#include +#include + +namespace ovdl::detail { + template> + class BasicCallbackStreamBuffer : public std::basic_streambuf { + public: + using base_type = std::basic_streambuf; + using callback_type = Callback; + using char_type = typename base_type::char_type; + using int_type = typename base_type::int_type; + + BasicCallbackStreamBuffer(Callback cb, void* user_data = nullptr) + : _callback(cb), + _user_data(user_data) {} + + protected: + std::streamsize xsputn(const char_type* s, std::streamsize n) override { + if constexpr (std::is_same_v) { + _callback(s, n, _user_data); + return n; + } else { + return _callback(s, n, _user_data); // returns the number of characters successfully written. + } + }; + + int_type overflow(int_type ch) override { + if constexpr (std::is_same_v) { + _callback(&ch, 1, _user_data); + return 1; + } else { + return _callback(&ch, 1, _user_data); // returns the number of characters successfully written. + } + } + + private: + Callback _callback; + void* _user_data; + }; + + template + class CallbackStreamBuffer : public BasicCallbackStreamBuffer { + public: + using base_type = BasicCallbackStreamBuffer; + using callback_type = Callback; + using char_type = typename base_type::char_type; + using int_type = typename base_type::int_type; + + CallbackStreamBuffer(Callback cb, void* user_data = nullptr) : base_type(cb, user_data) {} + }; + + template + class CallbackWStreamBuffer : public BasicCallbackStreamBuffer { + public: + using base_type = BasicCallbackStreamBuffer; + using callback_type = Callback; + using char_type = typename base_type::char_type; + using int_type = typename base_type::int_type; + + CallbackWStreamBuffer(Callback cb, void* user_data = nullptr) : base_type(cb, user_data) {} + }; + + template> + class BasicCallbackStream : public std::basic_ostream { + public: + using base_type = std::basic_ostream; + + BasicCallbackStream(Callback cb, void* user_data = nullptr) + : m_sbuf(cb, user_data), + std::basic_ios(&m_sbuf), + std::basic_ostream(&m_sbuf) { + std::basic_ios::init(&m_sbuf); + } + + private: + BasicCallbackStreamBuffer m_sbuf; + }; + + template + class CallbackStream : public BasicCallbackStream { + public: + using base_type = BasicCallbackStream; + + CallbackStream(Callback cb, void* user_data = nullptr) : base_type(cb, user_data) { + } + }; + + template + class CallbackWStream : public BasicCallbackStream { + public: + using base_type = BasicCallbackStream; + + CallbackWStream(Callback cb, void* user_data = nullptr) : base_type(cb, user_data) { + } + }; +} \ No newline at end of file diff --git a/include/openvic-dataloader/detail/Concepts.hpp b/include/openvic-dataloader/detail/Concepts.hpp new file mode 100644 index 0000000..3e1c785 --- /dev/null +++ b/include/openvic-dataloader/detail/Concepts.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include +#include +#include +#include + +#include + +namespace ovdl::detail { + template + concept LoadCallback = + requires(T t, Self* self, Args... args) { + { t(self, std::forward(args)...) } -> std::same_as>; + }; + + template + concept Has_c_str = + requires(T t) { + { t.c_str() } -> std::same_as; + }; +} \ No newline at end of file diff --git a/include/openvic-dataloader/detail/SelfType.hpp b/include/openvic-dataloader/detail/SelfType.hpp new file mode 100644 index 0000000..5209700 --- /dev/null +++ b/include/openvic-dataloader/detail/SelfType.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include + +namespace ovdl::detail { +#if !defined(_MSC_VER) +#pragma GCC diagnostic push +#pragma clang diagnostic ignored "-Wunknown-warning-option" +#pragma GCC diagnostic ignored "-Wnon-template-friend" +#endif + template + struct Reader { + friend auto adl_GetSelfType(Reader); + }; + + template + struct Writer { + friend auto adl_GetSelfType(Reader) { return U {}; } + }; +#if !defined(_MSC_VER) +#pragma GCC diagnostic pop +#endif + + inline void adl_GetSelfType() {} + + template + using Read = std::remove_pointer_t {}))>; +} diff --git a/include/openvic-dataloader/detail/TypeName.hpp b/include/openvic-dataloader/detail/TypeName.hpp new file mode 100644 index 0000000..1a34a0f --- /dev/null +++ b/include/openvic-dataloader/detail/TypeName.hpp @@ -0,0 +1,52 @@ +#pragma once + +#include +#include +#include +#include + +namespace ovdl::detail { + + template + constexpr auto substring_as_array(std::string_view str, std::index_sequence) { + return std::array { str[Idxs]... }; + } + + template + constexpr auto type_name_array() { +#if defined(__clang__) + constexpr auto prefix = std::string_view { "[T = " }; + constexpr auto suffix = std::string_view { "]" }; + constexpr auto function = std::string_view { __PRETTY_FUNCTION__ }; +#elif defined(__GNUC__) + constexpr auto prefix = std::string_view { "with T = " }; + constexpr auto suffix = std::string_view { "]" }; + constexpr auto function = std::string_view { __PRETTY_FUNCTION__ }; +#elif defined(_MSC_VER) + constexpr auto prefix = std::string_view { "type_name_array<" }; + constexpr auto suffix = std::string_view { ">(void)" }; + constexpr auto function = std::string_view { __FUNCSIG__ }; +#else +#error Unsupported compiler +#endif + + constexpr auto start = function.find(prefix) + prefix.size(); + constexpr auto end = function.rfind(suffix); + + static_assert(start < end); + + constexpr auto name = function.substr(start, (end - start)); + return substring_as_array(name, std::make_index_sequence {}); + } + + template + struct type_name_holder { + static inline constexpr auto value = type_name_array(); + }; + + template + constexpr auto type_name() -> std::string_view { + constexpr auto& value = type_name_holder::value; + return std::string_view { value.data(), value.size() }; + } +} \ No newline at end of file -- cgit v1.2.3-56-ga3b1