Skip to content

Commit c889394

Browse files
committed
WIP
1 parent 370133e commit c889394

File tree

1 file changed

+58
-17
lines changed

1 file changed

+58
-17
lines changed

src/script_parser.cpp

Lines changed: 58 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)