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/csv/LineObject.hpp | 84 +++++++++++++++++++++++++++ include/openvic-dataloader/csv/Parser.hpp | 42 ++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 include/openvic-dataloader/csv/LineObject.hpp create mode 100644 include/openvic-dataloader/csv/Parser.hpp (limited to 'include/openvic-dataloader/csv') diff --git a/include/openvic-dataloader/csv/LineObject.hpp b/include/openvic-dataloader/csv/LineObject.hpp new file mode 100644 index 0000000..0494ffb --- /dev/null +++ b/include/openvic-dataloader/csv/LineObject.hpp @@ -0,0 +1,84 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace ovdl::csv { + /// LineObject should be able to recognize the differences between: + /// Input -> Indexes == "" + /// ;;a;b;c;; -> 0,1,5,6+ == "" + /// a;b;c -> 3+ == "" + /// a;;b;c;; -> 1,4,5+ == "" + /// a;b;;c; -> 2,4+ == "" + /// a;b;c;; -> 3,4+ == "" + /// a;b;c; -> 3+ == "" + /// ;a;b;c -> 0,4+ == "" + /// + /// If this is incorrect, please report an issue. + class LineObject final : public std::vector> { + public: + // Stored position of value + using position_type = std::uint32_t; + // Value + using inner_value_type = std::string; + using container_type = std::vector>; + + constexpr LineObject() = default; + constexpr LineObject(LineObject&) = default; + constexpr LineObject(LineObject&&) = default; + constexpr LineObject(const LineObject&) = default; + + constexpr LineObject& operator=(const LineObject& other) = default; + constexpr LineObject& operator=(LineObject&& other) = default; + + constexpr ~LineObject() = default; + + constexpr LineObject(std::initializer_list pos_and_val) : container_type(pos_and_val) { + } + + constexpr LineObject(position_type prefix_end, std::initializer_list pos_and_val, position_type suffix_end = 0) + : container_type(pos_and_val), + _prefix_end(prefix_end), + _suffix_end(suffix_end) { + } + + /// Special Functionality + /// Retrieves value, produces "" for empty values + constexpr std::string_view get_value_for(std::size_t position) const { + if (position <= _prefix_end || position >= _suffix_end) return ""; + for (const auto& [pos, val] : *this) { + if (pos == position) return val; + } + return ""; + } + /// Tries to retrieve reference, produces nullopt for empty values + constexpr std::optional> try_get_string_at(std::size_t position) const { + if (position <= _prefix_end || position > _suffix_end) return std::nullopt; + for (const auto& [pos, val] : *this) { + if (pos == position) return std::cref(val); + } + return std::nullopt; + } + + constexpr position_type prefix_end() const { return _prefix_end; } + constexpr void set_prefix_end(position_type value) { _prefix_end = value; } + + constexpr position_type suffix_end() const { return _suffix_end; } + constexpr void set_suffix_end(position_type value) { _suffix_end = value; } + + constexpr std::size_t value_count() const { return _suffix_end; } + + private: + // Should be position of first valid value on line + position_type _prefix_end; + // Should be position after last value or position after last seperator + position_type _suffix_end; + }; +} \ No newline at end of file diff --git a/include/openvic-dataloader/csv/Parser.hpp b/include/openvic-dataloader/csv/Parser.hpp new file mode 100644 index 0000000..3497864 --- /dev/null +++ b/include/openvic-dataloader/csv/Parser.hpp @@ -0,0 +1,42 @@ +#pragma once + +#include +#include + +namespace ovdl::csv { + class Parser final : public detail::BasicParser { + public: + Parser(); + + static Parser from_buffer(const char* data, std::size_t size); + static Parser from_buffer(const char* start, const char* end); + static Parser from_string(const std::string_view string); + static Parser from_file(const char* path); + static Parser from_file(const std::filesystem::path& path); + + constexpr Parser& load_from_buffer(const char* data, std::size_t size); + constexpr Parser& load_from_buffer(const char* start, const char* end); + constexpr Parser& load_from_string(const std::string_view string); + constexpr Parser& load_from_file(const char* path); + Parser& load_from_file(const std::filesystem::path& path); + + constexpr Parser& load_from_file(const detail::Has_c_str auto& path); + + bool parse_csv(); + + const std::vector get_lines() const; + + Parser(Parser&&); + Parser& operator=(Parser&&); + + ~Parser(); + + private: + class BufferHandler; + std::unique_ptr _buffer_handler; + std::vector _lines; + + template + constexpr void _run_load_func(detail::LoadCallback auto func, Args... args); + }; +} \ No newline at end of file -- cgit v1.2.3-56-ga3b1