From 458180da5e61887cd9f820e573f307d0a640128d Mon Sep 17 00:00:00 2001 From: Spartan322 Date: Sat, 11 May 2024 14:37:50 -0400 Subject: Fix bugs in #37 Fix error handling dropping errors Fix error handling segfaults Improve error messages --- src/openvic-dataloader/csv/Parser.cpp | 18 +++++++++++------ src/openvic-dataloader/detail/Parser.cpp | 7 +++++++ src/openvic-dataloader/detail/dsl.hpp | 6 +++--- .../v2script/DecisionGrammar.hpp | 2 +- .../v2script/ModifierGrammar.hpp | 4 ++-- src/openvic-dataloader/v2script/Parser.cpp | 23 +++++++++++++++------- src/openvic-dataloader/v2script/SimpleGrammar.hpp | 12 ++++++++--- 7 files changed, 50 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/openvic-dataloader/csv/Parser.cpp b/src/openvic-dataloader/csv/Parser.cpp index 849ea05..361f6ad 100644 --- a/src/openvic-dataloader/csv/Parser.cpp +++ b/src/openvic-dataloader/csv/Parser.cpp @@ -142,8 +142,8 @@ constexpr Parser& Parser::load_from_string(const std::string } template -constexpr Parser& Parser::load_from_file(const char* path) { - _file_path = path; +Parser& Parser::load_from_file(const char* path) { + set_file_path(path); // Type can be deduced?? _run_load_func(std::mem_fn(&ParseHandler::load_file), path); return *this; @@ -224,15 +224,21 @@ void Parser::print_errors_to(std::basic_ostream& stream) const { dryad::visit_tree( error, [&](const error::BufferError* buffer_error) { - stream << buffer_error->message() << '\n'; + stream << "buffer error: " << buffer_error->message() << '\n'; }, [&](const error::ParseError* parse_error) { - stream << parse_error->message() << '\n'; + auto position = get_error_position(parse_error); + std::string pos_str = fmt::format(":{}:{}: ", position.start_line, position.start_column); + stream << _file_path << pos_str << "parse error for '" << parse_error->production_name() << "': " << parse_error->message() << '\n'; }, [&](dryad::child_visitor visitor, const error::Semantic* semantic) { - stream << semantic->message() << '\n'; + auto position = get_error_position(semantic); + std::string pos_str = ": "; + if (!position.is_empty()) { + pos_str = fmt::format(":{}:{}: ", position.start_line, position.start_column); + } + stream << _file_path << pos_str << semantic->message() << '\n'; auto annotations = semantic->annotations(); - if (annotations.empty()) return; for (auto annotation : annotations) { visitor(annotation); } diff --git a/src/openvic-dataloader/detail/Parser.cpp b/src/openvic-dataloader/detail/Parser.cpp index fd87687..bb5c612 100644 --- a/src/openvic-dataloader/detail/Parser.cpp +++ b/src/openvic-dataloader/detail/Parser.cpp @@ -1,3 +1,4 @@ +#include #include #include @@ -40,4 +41,10 @@ bool BasicParser::has_warning() const { std::string_view BasicParser::get_file_path() const { return _file_path; +} + +void BasicParser::set_file_path(std::string_view path) { + std::error_code error; + std::filesystem::path file_path = std::filesystem::weakly_canonical(path, error); + _file_path = file_path.string(); } \ No newline at end of file diff --git a/src/openvic-dataloader/detail/dsl.hpp b/src/openvic-dataloader/detail/dsl.hpp index 9b544bc..ccc1af6 100644 --- a/src/openvic-dataloader/detail/dsl.hpp +++ b/src/openvic-dataloader/detail/dsl.hpp @@ -97,14 +97,14 @@ namespace ovdl::dsl { template< IsParseState ParseType, - typename Identifier, + auto 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 keyword = ovdl::dsl::keyword(Identifier); static constexpr auto rule = lexy::dsl::position(keyword) >> lexy::dsl::equal_sign; static constexpr auto value = Value; }; @@ -114,7 +114,7 @@ namespace ovdl::dsl { template< IsParseState ParseType, - typename Identifier, + auto Identifier, typename RuleValue, ovdl::detail::string_literal Keyword, auto Production, diff --git a/src/openvic-dataloader/v2script/DecisionGrammar.hpp b/src/openvic-dataloader/v2script/DecisionGrammar.hpp index 05cb8cc..b5010ff 100644 --- a/src/openvic-dataloader/v2script/DecisionGrammar.hpp +++ b/src/openvic-dataloader/v2script/DecisionGrammar.hpp @@ -40,7 +40,7 @@ namespace ovdl::v2script::grammar { struct DecisionList { static constexpr auto rule = - ovdl::dsl::keyword<"political_decisions">(lexy::dsl::inline_>) >> + ovdl::dsl::keyword<"political_decisions">(id) >> (lexy::dsl::equal_sign >> lexy::dsl::curly_bracketed.opt_list(lexy::dsl::p)); static constexpr auto value = lexy::as_list; diff --git a/src/openvic-dataloader/v2script/ModifierGrammar.hpp b/src/openvic-dataloader/v2script/ModifierGrammar.hpp index 5b937d5..d6dbb32 100644 --- a/src/openvic-dataloader/v2script/ModifierGrammar.hpp +++ b/src/openvic-dataloader/v2script/ModifierGrammar.hpp @@ -15,8 +15,8 @@ #include "detail/dsl.hpp" namespace ovdl::v2script::grammar { - constexpr auto modifier_keyword = LEXY_KEYWORD("modifier", lexy::dsl::inline_>); - constexpr auto factor_keyword = LEXY_KEYWORD("factor", lexy::dsl::inline_>); + constexpr auto modifier_keyword = LEXY_KEYWORD("modifier", id); + constexpr auto factor_keyword = LEXY_KEYWORD("factor", id); struct FactorStatement { static constexpr auto rule = lexy::dsl::position(factor_keyword) >> (lexy::dsl::equal_sign + lexy::dsl::p>); diff --git a/src/openvic-dataloader/v2script/Parser.cpp b/src/openvic-dataloader/v2script/Parser.cpp index 29e9e80..a4cad9d 100644 --- a/src/openvic-dataloader/v2script/Parser.cpp +++ b/src/openvic-dataloader/v2script/Parser.cpp @@ -1,5 +1,6 @@ #include "openvic-dataloader/v2script/Parser.hpp" +#include #include #include #include @@ -149,8 +150,8 @@ constexpr Parser& Parser::load_from_string(const std::string_view string) { return load_from_buffer(string.data(), string.size()); } -constexpr Parser& Parser::load_from_file(const char* path) { - _file_path = path; +Parser& Parser::load_from_file(const char* path) { + set_file_path(path); // Type can be deduced?? _run_load_func(std::mem_fn(&ParseHandler::load_file), path); return *this; @@ -179,6 +180,7 @@ bool Parser::simple_parse() { _has_error = _parse_handler->parse_state().logger().errored(); _has_warning = _parse_handler->parse_state().logger().warned(); if (!_parse_handler->root()) { + _has_error = true; _has_fatal_error = true; if (&_error_stream.get() != &detail::cnull) { print_errors_to(_error_stream); @@ -258,8 +260,8 @@ const FileTree* Parser::get_file_node() const { return _parse_handler->root(); } -std::string_view Parser::value(const ovdl::v2script::ast::FlatValue& node) const { - return node.value(_parse_handler->parse_state().ast().symbol_interner()); +std::string_view Parser::value(const ovdl::v2script::ast::FlatValue* node) const { + return node->value(_parse_handler->parse_state().ast().symbol_interner()); } std::string Parser::make_native_string() const { @@ -319,13 +321,20 @@ void Parser::print_errors_to(std::basic_ostream& stream) const { dryad::visit_tree( error, [&](const error::BufferError* buffer_error) { - stream << buffer_error->message() << '\n'; + stream << "buffer error: " << buffer_error->message() << '\n'; }, [&](const error::ParseError* parse_error) { - stream << parse_error->message() << '\n'; + auto position = get_error_position(parse_error); + std::string pos_str = fmt::format(":{}:{}: ", position.start_line, position.start_column); + stream << _file_path << pos_str << "parse error for '" << parse_error->production_name() << "': " << parse_error->message() << '\n'; }, [&](dryad::child_visitor visitor, const error::Semantic* semantic) { - stream << semantic->message() << '\n'; + auto position = get_error_position(semantic); + std::string pos_str = ": "; + if (!position.is_empty()) { + pos_str = fmt::format(":{}:{}: ", position.start_line, position.start_column); + } + stream << _file_path << pos_str << semantic->message() << '\n'; auto annotations = semantic->annotations(); for (auto annotation : annotations) { visitor(annotation); diff --git a/src/openvic-dataloader/v2script/SimpleGrammar.hpp b/src/openvic-dataloader/v2script/SimpleGrammar.hpp index bd4adaa..731a7f1 100644 --- a/src/openvic-dataloader/v2script/SimpleGrammar.hpp +++ b/src/openvic-dataloader/v2script/SimpleGrammar.hpp @@ -5,6 +5,8 @@ #include #include +#include +#include #include "detail/dsl.hpp" @@ -37,12 +39,14 @@ namespace ovdl::v2script::grammar { /* REQUIREMENTS: DAT-631 */ static constexpr auto comment_specifier = LEXY_LIT("#") >> lexy::dsl::until(lexy::dsl::newline).or_eof(); + static constexpr auto ascii = lexy::dsl::ascii::alpha_digit_underscore / LEXY_ASCII_ONE_OF("+:@%&'-."); + /* REQUIREMENTS: * DAT-632 * DAT-635 */ static constexpr auto windows_1252_data_specifier = - lexy::dsl::ascii::alpha_digit_underscore / LEXY_ASCII_ONE_OF("+:@%&'-.") / + ascii / lexy::dsl::lit_b<0x8A> / lexy::dsl::lit_b<0x8C> / lexy::dsl::lit_b<0x8E> / lexy::dsl::lit_b<0x92> / lexy::dsl::lit_b<0x97> / lexy::dsl::lit_b<0x9A> / lexy::dsl::lit_b<0x9C> / dsl::make_range<0x9E, 0x9F>() / @@ -74,6 +78,8 @@ namespace ovdl::v2script::grammar { .map<'r'>('\r') .map<'t'>('\t'); + static constexpr auto id = lexy::dsl::identifier(data_char_class); + template struct SimpleGrammar { struct StatementListBlock; @@ -194,14 +200,14 @@ namespace ovdl::v2script::grammar { template> using keyword_rule = dsl::keyword_rule< ast::ParseState, - Identifier, + id, ast::AssignStatement, Keyword, Production, Value>; template> using fkeyword_rule = dsl::fkeyword_rule< ast::ParseState, - Identifier, + id, ast::AssignStatement, Keyword, Production, Value>; -- cgit v1.2.3-56-ga3b1