diff options
author | Spartan322 <Megacake1234@gmail.com> | 2023-11-28 11:09:26 +0100 |
---|---|---|
committer | Spartan322 <Megacake1234@gmail.com> | 2024-05-09 22:11:26 +0200 |
commit | 757114a3c5b748567b42f273c7b78ca039ae983c (patch) | |
tree | e07390b682052129c91f4b157068bcdd84ceecb4 /include/openvic-dataloader/detail/LexyReportError.hpp | |
parent | 7211a228e68c8a6b1ad1c1c5ec68c8d720b6d2ba (diff) |
Add `deps/dryad` -> https://github.com/Spartan322/dryadadd/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`
Diffstat (limited to 'include/openvic-dataloader/detail/LexyReportError.hpp')
-rw-r--r-- | include/openvic-dataloader/detail/LexyReportError.hpp | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/include/openvic-dataloader/detail/LexyReportError.hpp b/include/openvic-dataloader/detail/LexyReportError.hpp new file mode 100644 index 0000000..3c32bd1 --- /dev/null +++ b/include/openvic-dataloader/detail/LexyReportError.hpp @@ -0,0 +1,107 @@ +#pragma once + +#include <cstddef> +#include <sstream> +#include <utility> +#include <vector> + +#include <openvic-dataloader/ParseData.hpp> +#include <openvic-dataloader/ParseError.hpp> + +#include <lexy/input_location.hpp> +#include <lexy/visualize.hpp> + +#include "openvic-dataloader/detail/utility/Concepts.hpp" + +#include <lexy_ext/report_error.hpp> + +namespace ovdl::detail { + template<typename OutputIterator> + struct _ReportError { + OutputIterator _iter; + lexy::visualization_options _opts; + const char* _path; + + struct _sink { + OutputIterator _iter; + lexy::visualization_options _opts; + const char* _path; + std::size_t _count; + std::vector<ParseError> _errors; + + using return_type = std::vector<ParseError>; + + template<typename Input, typename Reader, typename Tag> + void operator()(const lexy::error_context<Input>& context, const lexy::error<Reader, Tag>& error) { + _iter = lexy_ext::_detail::write_error(_iter, context, error, _opts, _path); + ++_count; + + // Convert the context location and error location into line/column information. + auto context_location = lexy::get_input_location(context.input(), context.position()); + auto location = lexy::get_input_location(context.input(), error.position(), context_location.anchor()); + + std::basic_stringstream<typename Reader::encoding::char_type> message; + + // Write the main annotation. + if constexpr (std::is_same_v<Tag, lexy::expected_literal>) { + auto string = lexy::_detail::make_literal_lexeme<typename Reader::encoding>(error.string(), error.length()); + + message << "expected '" << string.data() << '\''; + } else if constexpr (std::is_same_v<Tag, lexy::expected_keyword>) { + auto string = lexy::_detail::make_literal_lexeme<typename Reader::encoding>(error.string(), error.length()); + + message << "expected keyword '" << string.data() << '\''; + } else if constexpr (std::is_same_v<Tag, lexy::expected_char_class>) { + message << "expected " << error.name(); + } else { + message << error.message(); + } + + _errors.push_back( + ParseError { + ParseError::Type::Fatal, // TODO: distinguish recoverable errors from fatal errors + std::move(message.str()), + 0, // TODO: implement proper error codes + ParseData { + context.production(), + context_location.line_nr(), + context_location.column_nr(), + }, + location.line_nr(), + location.column_nr(), + }); + } + + return_type finish() && { + if (_count != 0) + *_iter++ = '\n'; + return _errors; + } + }; + constexpr auto sink() const { + return _sink { _iter, _opts, _path, 0 }; + } + + /// Specifies a path that will be printed alongside the diagnostic. + constexpr _ReportError path(const char* path) const { + return { _iter, _opts, path }; + } + + constexpr _ReportError path(const detail::HasCstr auto& path_object) const { + return path(path_object.c_str()); + } + + /// Specifies an output iterator where the errors are written to. + template<typename OI> + constexpr _ReportError<OI> to(OI out) const { + return { out, _opts, _path }; + } + + /// Overrides visualization options. + constexpr _ReportError opts(lexy::visualization_options opts) const { + return { _iter, opts, _path }; + } + }; + + constexpr auto ReporError = _ReportError<lexy::stderr_output_iterator> {}; +}
\ No newline at end of file |