diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/openvic-dataloader/ParseData.hpp | 11 | ||||
-rw-r--r-- | include/openvic-dataloader/ParseError.hpp | 20 | ||||
-rw-r--r-- | include/openvic-dataloader/ParseWarning.hpp | 10 | ||||
-rw-r--r-- | include/openvic-dataloader/csv/LineObject.hpp | 84 | ||||
-rw-r--r-- | include/openvic-dataloader/csv/Parser.hpp | 42 | ||||
-rw-r--r-- | include/openvic-dataloader/detail/BasicParser.hpp | 37 | ||||
-rw-r--r-- | include/openvic-dataloader/detail/CallbackOStream.hpp | 100 | ||||
-rw-r--r-- | include/openvic-dataloader/detail/Concepts.hpp | 22 | ||||
-rw-r--r-- | include/openvic-dataloader/detail/SelfType.hpp | 28 | ||||
-rw-r--r-- | include/openvic-dataloader/detail/TypeName.hpp | 52 | ||||
-rw-r--r-- | include/openvic-dataloader/v2script/AbstractSyntaxTree.hpp | 224 | ||||
-rw-r--r-- | include/openvic-dataloader/v2script/Parser.hpp | 58 |
12 files changed, 675 insertions, 13 deletions
diff --git a/include/openvic-dataloader/ParseData.hpp b/include/openvic-dataloader/ParseData.hpp new file mode 100644 index 0000000..8bec7d2 --- /dev/null +++ b/include/openvic-dataloader/ParseData.hpp @@ -0,0 +1,11 @@ +#pragma once + +#include <string> + +namespace ovdl { + struct ParseData { + const std::string production_name; + const unsigned int context_start_line; + const unsigned int context_start_column; + }; +}
\ No newline at end of file diff --git a/include/openvic-dataloader/ParseError.hpp b/include/openvic-dataloader/ParseError.hpp new file mode 100644 index 0000000..9e4541e --- /dev/null +++ b/include/openvic-dataloader/ParseError.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include <string> + +#include <openvic-dataloader/ParseData.hpp> + +namespace ovdl { + struct ParseError { + const enum class Type : unsigned char { + Recoverable, + Fatal + } type; + const std::string message; + const int error_value; + const ParseData parse_data; + const unsigned int start_line; + const unsigned int start_column; + }; + +}
\ No newline at end of file diff --git a/include/openvic-dataloader/ParseWarning.hpp b/include/openvic-dataloader/ParseWarning.hpp new file mode 100644 index 0000000..307599f --- /dev/null +++ b/include/openvic-dataloader/ParseWarning.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include <string> + +namespace ovdl { + struct ParseWarning { + const std::string message; + const int warning_value; + }; +}
\ No newline at end of file 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 <cstddef> +#include <cstdint> +#include <functional> +#include <initializer_list> +#include <optional> +#include <string> +#include <string_view> +#include <tuple> +#include <vector> + +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<std::tuple<std::uint32_t, std::string>> { + public: + // Stored position of value + using position_type = std::uint32_t; + // Value + using inner_value_type = std::string; + using container_type = std::vector<std::tuple<position_type, inner_value_type>>; + + 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<value_type> pos_and_val) : container_type(pos_and_val) { + } + + constexpr LineObject(position_type prefix_end, std::initializer_list<value_type> 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<const std::reference_wrapper<const std::string>> 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 <openvic-dataloader/csv/LineObject.hpp> +#include <openvic-dataloader/detail/BasicParser.hpp> + +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<csv::LineObject> get_lines() const; + + Parser(Parser&&); + Parser& operator=(Parser&&); + + ~Parser(); + + private: + class BufferHandler; + std::unique_ptr<BufferHandler> _buffer_handler; + std::vector<csv::LineObject> _lines; + + template<typename... Args> + constexpr void _run_load_func(detail::LoadCallback<BufferHandler, Args...> auto func, Args... args); + }; +}
\ No newline at end of file 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 <filesystem> +#include <optional> +#include <string_view> +#include <vector> + +#include <openvic-dataloader/ParseError.hpp> +#include <openvic-dataloader/ParseWarning.hpp> +#include <openvic-dataloader/detail/Concepts.hpp> + +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<char>& stream); + + bool has_error() const; + bool has_fatal_error() const; + bool has_warning() const; + + const std::vector<ParseError>& get_errors() const; + const std::vector<ParseWarning>& get_warnings() const; + + protected: + std::vector<ParseError> _errors; + std::vector<ParseWarning> _warnings; + + std::reference_wrapper<std::ostream> _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 <cstring> +#include <functional> +#include <ostream> +#include <type_traits> + +namespace ovdl::detail { + template<typename Callback, class CHAR_T, class traits = std::char_traits<CHAR_T>> + class BasicCallbackStreamBuffer : public std::basic_streambuf<CHAR_T, traits> { + public: + using base_type = std::basic_streambuf<CHAR_T, traits>; + 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<void, typename decltype(std::function { _callback })::result_type>) { + _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<void, typename decltype(std::function { _callback })::result_type>) { + _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<typename Callback> + class CallbackStreamBuffer : public BasicCallbackStreamBuffer<Callback, char> { + public: + using base_type = BasicCallbackStreamBuffer<Callback, char>; + 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<typename Callback> + class CallbackWStreamBuffer : public BasicCallbackStreamBuffer<Callback, wchar_t> { + public: + using base_type = BasicCallbackStreamBuffer<Callback, wchar_t>; + 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<typename Callback, class CHAR_T, class traits = std::char_traits<CHAR_T>> + class BasicCallbackStream : public std::basic_ostream<CHAR_T, traits> { + public: + using base_type = std::basic_ostream<CHAR_T, traits>; + + BasicCallbackStream(Callback cb, void* user_data = nullptr) + : m_sbuf(cb, user_data), + std::basic_ios<CHAR_T, traits>(&m_sbuf), + std::basic_ostream<CHAR_T, traits>(&m_sbuf) { + std::basic_ios<CHAR_T, traits>::init(&m_sbuf); + } + + private: + BasicCallbackStreamBuffer<Callback, CHAR_T, traits> m_sbuf; + }; + + template<typename Callback> + class CallbackStream : public BasicCallbackStream<Callback, char> { + public: + using base_type = BasicCallbackStream<Callback, char>; + + CallbackStream(Callback cb, void* user_data = nullptr) : base_type(cb, user_data) { + } + }; + + template<typename Callback> + class CallbackWStream : public BasicCallbackStream<Callback, wchar_t> { + public: + using base_type = BasicCallbackStream<Callback, wchar_t>; + + 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 <concepts> +#include <optional> +#include <type_traits> +#include <utility> + +#include <openvic-dataloader/ParseError.hpp> + +namespace ovdl::detail { + template<typename T, typename Self, typename... Args> + concept LoadCallback = + requires(T t, Self* self, Args... args) { + { t(self, std::forward<Args>(args)...) } -> std::same_as<std::optional<ParseError>>; + }; + + template<typename T> + concept Has_c_str = + requires(T t) { + { t.c_str() } -> std::same_as<const char*>; + }; +}
\ 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 <type_traits> + +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<typename T> + struct Reader { + friend auto adl_GetSelfType(Reader<T>); + }; + + template<typename T, typename U> + struct Writer { + friend auto adl_GetSelfType(Reader<T>) { return U {}; } + }; +#if !defined(_MSC_VER) +#pragma GCC diagnostic pop +#endif + + inline void adl_GetSelfType() {} + + template<typename T> + using Read = std::remove_pointer_t<decltype(adl_GetSelfType(Reader<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 <array> +#include <cstddef> +#include <string_view> +#include <utility> + +namespace ovdl::detail { + + template<std::size_t... Idxs> + constexpr auto substring_as_array(std::string_view str, std::index_sequence<Idxs...>) { + return std::array { str[Idxs]... }; + } + + template<typename T> + 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<name.size()> {}); + } + + template<typename T> + struct type_name_holder { + static inline constexpr auto value = type_name_array<T>(); + }; + + template<typename T> + constexpr auto type_name() -> std::string_view { + constexpr auto& value = type_name_holder<T>::value; + return std::string_view { value.data(), value.size() }; + } +}
\ No newline at end of file diff --git a/include/openvic-dataloader/v2script/AbstractSyntaxTree.hpp b/include/openvic-dataloader/v2script/AbstractSyntaxTree.hpp new file mode 100644 index 0000000..7b382fd --- /dev/null +++ b/include/openvic-dataloader/v2script/AbstractSyntaxTree.hpp @@ -0,0 +1,224 @@ +#pragma once + +#include <iostream> +#include <memory> +#include <optional> +#include <string> +#include <string_view> +#include <type_traits> +#include <utility> +#include <vector> + +#include <openvic-dataloader/detail/SelfType.hpp> +#include <openvic-dataloader/detail/TypeName.hpp> + +#define OVDL_PRINT_FUNC_DEF std::ostream& print(std::ostream& stream, size_t indent) const override + +// defines get_type_static and get_type for string type naming +#define OVDL_RT_TYPE_DEF \ + static constexpr std::string_view get_type_static() { return ::ovdl::detail::type_name<type>(); } \ + constexpr std::string_view get_type() const override { return ::ovdl::detail::type_name<std::decay_t<decltype(*this)>>(); } + +// defines type for self-class referencing +#define OVDL_TYPE_DEFINE_SELF \ + struct _self_type_tag {}; \ + constexpr auto _self_type_helper()->decltype(::ovdl::detail::Writer<_self_type_tag, decltype(this)> {}); \ + using type = ::ovdl::detail::Read<_self_type_tag>; + +namespace ovdl::v2script::ast { + + struct Node; + using NodePtr = Node*; + using NodeCPtr = const Node*; + using NodeUPtr = std::unique_ptr<Node>; + + struct Node { + Node(const Node&) = delete; + Node& operator=(const Node&) = delete; + Node() = default; + Node(Node&&) = default; + Node& operator=(Node&&) = default; + virtual ~Node() = default; + + virtual std::ostream& print(std::ostream& stream, size_t indent) const = 0; + static std::ostream& print_ptr(std::ostream& stream, NodeCPtr node, size_t indent); + explicit operator std::string() const; + + static constexpr std::string_view get_type_static() { return detail::type_name<Node>(); } + constexpr virtual std::string_view get_type() const = 0; + + template<typename T> + constexpr bool is_type() const { + return get_type().compare(detail::type_name<T>()) == 0; + } + + template<typename T> + constexpr std::optional<T&> cast_to() { + if (is_type<T>()) return static_cast<T>(*this); + return std::nullopt; + } + }; + + inline std::ostream& operator<<(std::ostream& stream, Node const& node) { + return node.print(stream, 0); + } + inline std::ostream& operator<<(std::ostream& stream, NodeCPtr node) { + return Node::print_ptr(stream, node, 0); + } + + template<class T, class... Args> + NodePtr make_node_ptr(Args&&... args) { + if constexpr (std::is_pointer_v<NodePtr>) { + return new T(std::forward<Args>(args)...); + } else { + return NodePtr(new T(std::forward<Args>(args)...)); + } + } + + template<typename To, typename From> + To& cast_node_ptr(const From& from) { + if constexpr (std::is_pointer_v<NodePtr>) { + return *static_cast<To*>(from); + } else { + return *static_cast<To*>(from.get()); + } + } + + template<typename To, typename From> + const To& cast_node_cptr(const From& from) { + if constexpr (std::is_pointer_v<NodePtr>) { + return *static_cast<const To*>(from); + } else { + return *static_cast<const To*>(from.get()); + } + } + + void copy_into_node_ptr_vector(const std::vector<NodePtr>& source, std::vector<NodeUPtr>& dest); + + struct AbstractStringNode : public Node { + std::string _name; + explicit AbstractStringNode(std::string&& name); + OVDL_TYPE_DEFINE_SELF; + OVDL_RT_TYPE_DEF; + OVDL_PRINT_FUNC_DEF; + }; + +#define OVDL_AST_STRING_NODE(NAME) \ + struct NAME final : public AbstractStringNode { \ + explicit NAME(std::string&& name); \ + OVDL_TYPE_DEFINE_SELF; \ + OVDL_RT_TYPE_DEF; \ + OVDL_PRINT_FUNC_DEF; \ + } + + // Value Expression Nodes + OVDL_AST_STRING_NODE(IdentifierNode); + OVDL_AST_STRING_NODE(StringNode); + + // Assignment Nodes + OVDL_AST_STRING_NODE(FactorNode); + OVDL_AST_STRING_NODE(MonthNode); + OVDL_AST_STRING_NODE(NameNode); + OVDL_AST_STRING_NODE(FireOnlyNode); + OVDL_AST_STRING_NODE(IdNode); + OVDL_AST_STRING_NODE(TitleNode); + OVDL_AST_STRING_NODE(DescNode); + OVDL_AST_STRING_NODE(PictureNode); + OVDL_AST_STRING_NODE(IsTriggeredNode); + +#undef OVDL_AST_STRING_NODE + + struct AssignNode final : public Node { + std::string _name; + NodeUPtr _initializer; + explicit AssignNode(NodeCPtr name, NodePtr init); + OVDL_TYPE_DEFINE_SELF; + OVDL_RT_TYPE_DEF; + OVDL_PRINT_FUNC_DEF; + }; + + struct AbstractListNode : public Node { + std::vector<NodeUPtr> _statements; + AbstractListNode(const std::vector<NodePtr>& statements = std::vector<NodePtr> {}); + OVDL_TYPE_DEFINE_SELF; + OVDL_RT_TYPE_DEF; + OVDL_PRINT_FUNC_DEF; + }; + +#define OVDL_AST_LIST_NODE(NAME) \ + struct NAME final : public AbstractListNode { \ + explicit NAME(const std::vector<NodePtr>& statements = std::vector<NodePtr> {}); \ + OVDL_TYPE_DEFINE_SELF; \ + OVDL_RT_TYPE_DEF; \ + OVDL_PRINT_FUNC_DEF; \ + } + + OVDL_AST_LIST_NODE(FileNode); + OVDL_AST_LIST_NODE(ListNode); + + OVDL_AST_LIST_NODE(ModifierNode); + OVDL_AST_LIST_NODE(MtthNode); + OVDL_AST_LIST_NODE(EventOptionNode); + OVDL_AST_LIST_NODE(BehaviorListNode); + OVDL_AST_LIST_NODE(DecisionListNode); + +#undef OVDL_AST_LIST_NODE + + struct EventNode final : public Node { + enum class Type { + Country, + Province + } _type; + std::vector<NodeUPtr> _statements; + explicit EventNode(Type type, const std::vector<NodePtr>& statements = {}); + OVDL_TYPE_DEFINE_SELF; + OVDL_RT_TYPE_DEF; + OVDL_PRINT_FUNC_DEF; + }; + + struct DecisionNode final : public Node { + NodeUPtr _name; + std::vector<NodeUPtr> _statements; + explicit DecisionNode(NodePtr name, const std::vector<NodePtr>& statements = {}); + OVDL_TYPE_DEFINE_SELF; + OVDL_RT_TYPE_DEF; + OVDL_PRINT_FUNC_DEF; + }; + + struct EventMtthModifierNode final : public Node { + NodeUPtr _factor_value; + std::vector<NodeUPtr> _statements; + EventMtthModifierNode() {} + OVDL_TYPE_DEFINE_SELF; + OVDL_RT_TYPE_DEF; + OVDL_PRINT_FUNC_DEF; + }; + + // Packed single case + struct ExecutionNode final : public Node { + enum class Type { + Effect, + Trigger + } _type; + NodeUPtr _name; + NodeUPtr _initializer; + explicit ExecutionNode(Type type, NodePtr name, NodePtr init); + OVDL_TYPE_DEFINE_SELF; + OVDL_RT_TYPE_DEF; + OVDL_PRINT_FUNC_DEF; + }; + + struct ExecutionListNode final : public Node { + ExecutionNode::Type _type; + std::vector<NodeUPtr> _statements; + explicit ExecutionListNode(ExecutionNode::Type type, const std::vector<NodePtr>& statements); + OVDL_TYPE_DEFINE_SELF; + OVDL_RT_TYPE_DEF; + OVDL_PRINT_FUNC_DEF; + }; + +} + +#undef OVDL_PRINT_FUNC_DECL +#undef OVDL_PRINT_FUNC_DEF +#undef OVDL_TYPE_DEFINE_SELF
\ No newline at end of file diff --git a/include/openvic-dataloader/v2script/Parser.hpp b/include/openvic-dataloader/v2script/Parser.hpp index 53aab90..1c524b2 100644 --- a/include/openvic-dataloader/v2script/Parser.hpp +++ b/include/openvic-dataloader/v2script/Parser.hpp @@ -1,27 +1,59 @@ #pragma once #include <cstddef> -#include <cstdio> +#include <filesystem> +#include <functional> +#include <memory> +#include <optional> #include <ostream> +#include <string_view> +#include <vector> + +#include <openvic-dataloader/ParseError.hpp> +#include <openvic-dataloader/ParseWarning.hpp> +#include <openvic-dataloader/detail/BasicParser.hpp> +#include <openvic-dataloader/detail/Concepts.hpp> +#include <openvic-dataloader/v2script/AbstractSyntaxTree.hpp> namespace ovdl::v2script { - class Parser { + + using FileNode = ast::FileNode; + + class Parser final : public detail::BasicParser { public: - static Parser from_buffer(char8_t* data, std::size_t size); - static Parser from_buffer(char8_t* start, char8_t* end); - static Parser from_file(const char8_t* path); + 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); - void set_error_log_to_stderr(); - void set_error_log_path(const char8_t* path); - void set_error_log_to(std::basic_ostream<char8_t> stream); - void set_error_log_to(std::FILE* file); + 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); - bool parse(); + constexpr Parser& load_from_file(const detail::Has_c_str auto& path); - bool has_error(); - bool has_warning(); + bool simple_parse(); + bool event_parse(); + bool decision_parse(); + + const FileNode* get_file_node() const; + + Parser(Parser&&); + Parser& operator=(Parser&&); + + ~Parser(); private: - Parser(); + class BufferHandler; + std::unique_ptr<BufferHandler> _buffer_handler; + std::unique_ptr<FileNode> _file_node; + + template<typename... Args> + constexpr void _run_load_func(detail::LoadCallback<BufferHandler, Args...> auto func, Args... args); }; }
\ No newline at end of file |