@@ -67,31 +67,72 @@ BT::Expected<Any> ParseScriptAndExecute(Ast::Environment& env, const std::string
6767 }
6868}
6969
70- Result ValidateScript ( const std::string& script)
70+ class SafeErrorReport
7171{
72- char error_msgs_buffer[2048 ];
72+ mutable std::string error_buffer;
73+ mutable std::size_t count = 0 ;
7374
74- auto input = lexy::string_input<lexy::utf8_encoding>(script);
75- auto result =
76- lexy::parse<BT::Grammar::stmt>(input, ErrorReport ().to (error_msgs_buffer));
77- if (result.has_value () && result.error_count () == 0 )
75+ struct _sink
7876 {
79- try
77+ std::string* buffer;
78+ std::size_t * count;
79+ using return_type = std::size_t ;
80+
81+ template <typename Input, typename Reader, typename Tag>
82+ void operator ()(const lexy::error_context<Input>& context,
83+ const lexy::error<Reader, Tag>& error)
8084 {
81- std::vector<BT::Ast::ExprBase::Ptr> exprs = LEXY_MOV (result).value ();
82- if (exprs.empty ())
83- {
84- return nonstd::make_unexpected (" Empty Script" );
85- }
86- // valid script
87- return {};
85+ *buffer += " error: while parsing " ;
86+ *buffer += context.production ();
87+ *buffer += " \n " ;
88+ (*count)++;
8889 }
89- catch (std::runtime_error& err)
90+
91+ std::size_t finish () &&
9092 {
91- return nonstd::make_unexpected (err.what ());
93+ return *count;
94+ }
95+ };
96+
97+ public:
98+ using return_type = std::size_t ;
99+
100+ constexpr auto sink () const
101+ {
102+ return _sink{ &error_buffer, &count };
103+ }
104+ const std::string& get_errors () const
105+ {
106+ return error_buffer;
107+ }
108+ };
109+
110+ Result ValidateScript (const std::string& script)
111+ {
112+ auto input = lexy::string_input<lexy::utf8_encoding>(script);
113+ SafeErrorReport error_report; // Replace char buffer with our safe handler
114+
115+ auto result = lexy::parse<BT::Grammar::stmt>(input, error_report);
116+
117+ if (!result.has_value () || result.error_count () != 0 )
118+ {
119+ return nonstd::make_unexpected (error_report.get_errors ());
120+ }
121+
122+ try
123+ {
124+ std::vector<BT::Ast::ExprBase::Ptr> exprs = LEXY_MOV (result).value ();
125+ if (exprs.empty ())
126+ {
127+ return nonstd::make_unexpected (" Empty Script" );
92128 }
129+ // valid script
130+ return {};
131+ }
132+ catch (std::runtime_error& err)
133+ {
134+ return nonstd::make_unexpected (err.what ());
93135 }
94- return nonstd::make_unexpected (error_msgs_buffer);
95136}
96137
97138} // namespace BT
0 commit comments