From c8893940ac5dafd656ad4abd06127f0beae2c39f Mon Sep 17 00:00:00 2001 From: Davide Faconti Date: Wed, 5 Feb 2025 01:32:24 +0100 Subject: [PATCH] WIP --- src/script_parser.cpp | 75 +++++++++++++++++++++++++++++++++---------- 1 file changed, 58 insertions(+), 17 deletions(-) diff --git a/src/script_parser.cpp b/src/script_parser.cpp index 5bbc62006..9e00fa78a 100644 --- a/src/script_parser.cpp +++ b/src/script_parser.cpp @@ -67,31 +67,72 @@ BT::Expected ParseScriptAndExecute(Ast::Environment& env, const std::string } } -Result ValidateScript(const std::string& script) +class SafeErrorReport { - char error_msgs_buffer[2048]; + mutable std::string error_buffer; + mutable std::size_t count = 0; - auto input = lexy::string_input(script); - auto result = - lexy::parse(input, ErrorReport().to(error_msgs_buffer)); - if(result.has_value() && result.error_count() == 0) + struct _sink { - try + std::string* buffer; + std::size_t* count; + using return_type = std::size_t; + + template + void operator()(const lexy::error_context& context, + const lexy::error& error) { - std::vector exprs = LEXY_MOV(result).value(); - if(exprs.empty()) - { - return nonstd::make_unexpected("Empty Script"); - } - // valid script - return {}; + *buffer += "error: while parsing "; + *buffer += context.production(); + *buffer += "\n"; + (*count)++; } - catch(std::runtime_error& err) + + std::size_t finish() && { - return nonstd::make_unexpected(err.what()); + return *count; + } + }; + +public: + using return_type = std::size_t; + + constexpr auto sink() const + { + return _sink{ &error_buffer, &count }; + } + const std::string& get_errors() const + { + return error_buffer; + } +}; + +Result ValidateScript(const std::string& script) +{ + auto input = lexy::string_input(script); + SafeErrorReport error_report; // Replace char buffer with our safe handler + + auto result = lexy::parse(input, error_report); + + if(!result.has_value() || result.error_count() != 0) + { + return nonstd::make_unexpected(error_report.get_errors()); + } + + try + { + std::vector exprs = LEXY_MOV(result).value(); + if(exprs.empty()) + { + return nonstd::make_unexpected("Empty Script"); } + // valid script + return {}; + } + catch(std::runtime_error& err) + { + return nonstd::make_unexpected(err.what()); } - return nonstd::make_unexpected(error_msgs_buffer); } } // namespace BT