mirror of
https://github.com/boostorg/parser.git
synced 2026-01-29 19:52:12 +00:00
Add iterators to the beginning and end of the entire parsed sequence to the
context, and improve the error/warning reporting mechanism.
This commit is contained in:
@@ -153,15 +153,30 @@ namespace boost { namespace parser {
|
||||
return error_handler_result::fail;
|
||||
}
|
||||
|
||||
template<typename Iter>
|
||||
void
|
||||
warn(Iter first, Iter it, Iter last, std::string_view message) const
|
||||
template<typename Context, typename Iter>
|
||||
void diagnose(
|
||||
diagnostic_kind kind,
|
||||
std::string_view message,
|
||||
Context const & context,
|
||||
Iter it) const
|
||||
{
|
||||
if (!warning_)
|
||||
callback_type const & cb =
|
||||
kind == diagnostic_kind::error ? error_ : warning_;
|
||||
if (!cb)
|
||||
return;
|
||||
std::stringstream ss;
|
||||
write_formatted_message(ss, filename_, first, it, last, message);
|
||||
warning_(ss.str());
|
||||
parser::write_formatted_message(
|
||||
ss, filename_, _begin(context), it, _end(context), message);
|
||||
cb(ss.str());
|
||||
}
|
||||
|
||||
template<typename Context>
|
||||
void diagnose(
|
||||
diagnostic_kind kind,
|
||||
std::string_view message,
|
||||
Context const & context) const
|
||||
{
|
||||
diagnose(kind, message, context, _where(context).begin());
|
||||
}
|
||||
|
||||
callback_type error_;
|
||||
|
||||
@@ -50,6 +50,9 @@ namespace boost { namespace parser {
|
||||
int64_t preferred_max_line_length = 80,
|
||||
int64_t max_after_caret = 40);
|
||||
|
||||
// TODO: Add info kind as well?
|
||||
enum class diagnostic_kind { error, warning };
|
||||
|
||||
struct default_error_handler
|
||||
{
|
||||
constexpr default_error_handler() : os_(nullptr) {}
|
||||
@@ -68,11 +71,32 @@ namespace boost { namespace parser {
|
||||
operator()(Iter first, Iter last, parse_error<Iter> const & e) const
|
||||
{
|
||||
std::ostream & os = os_ ? *os_ : std::cout;
|
||||
write_formatted_expectation_failure_error_message(
|
||||
parser::write_formatted_expectation_failure_error_message(
|
||||
os, filename_, first, last, e);
|
||||
return error_handler_result::fail;
|
||||
}
|
||||
|
||||
template<typename Context, typename Iter>
|
||||
void diagnose(
|
||||
diagnostic_kind kind,
|
||||
std::string_view message,
|
||||
Context const & context,
|
||||
Iter it) const
|
||||
{
|
||||
std::ostream & os = os_ ? *os_ : std::cout;
|
||||
parser::write_formatted_message(
|
||||
os, filename_, _begin(context), it, _end(context), message);
|
||||
}
|
||||
|
||||
template<typename Context>
|
||||
void diagnose(
|
||||
diagnostic_kind kind,
|
||||
std::string_view message,
|
||||
Context const & context) const
|
||||
{
|
||||
diagnose(kind, message, context, _where(context).begin());
|
||||
}
|
||||
|
||||
std::string_view filename_;
|
||||
std::ostream * os_;
|
||||
};
|
||||
|
||||
@@ -95,8 +95,10 @@ namespace boost { namespace parser {
|
||||
|
||||
using symbol_table_tries_t = std::map<void *, any, std::less<void *>>;
|
||||
|
||||
template<typename ErrorHandler>
|
||||
template<typename Iter, typename ErrorHandler>
|
||||
inline auto make_context(
|
||||
Iter first,
|
||||
Iter last,
|
||||
bool & success,
|
||||
int & indent,
|
||||
ErrorHandler const & error_handler,
|
||||
@@ -104,6 +106,8 @@ namespace boost { namespace parser {
|
||||
symbol_table_tries_t & symbol_table_tries) noexcept
|
||||
{
|
||||
return hana::make_map(
|
||||
hana::make_pair(hana::type_c<begin_tag>, first),
|
||||
hana::make_pair(hana::type_c<end_tag>, last),
|
||||
hana::make_pair(hana::type_c<pass_tag>, &success),
|
||||
hana::make_pair(hana::type_c<val_tag>, global_nope),
|
||||
hana::make_pair(hana::type_c<attr_tag>, global_nope),
|
||||
@@ -118,8 +122,10 @@ namespace boost { namespace parser {
|
||||
hana::type_c<symbol_table_tries_tag>, &symbol_table_tries));
|
||||
}
|
||||
|
||||
template<typename ErrorHandler, typename GlobalState>
|
||||
template<typename Iter, typename ErrorHandler, typename GlobalState>
|
||||
inline auto make_context(
|
||||
Iter first,
|
||||
Iter last,
|
||||
bool & success,
|
||||
int & indent,
|
||||
ErrorHandler const & error_handler,
|
||||
@@ -127,6 +133,8 @@ namespace boost { namespace parser {
|
||||
symbol_table_tries_t & symbol_table_tries) noexcept
|
||||
{
|
||||
return hana::make_map(
|
||||
hana::make_pair(hana::type_c<begin_tag>, first),
|
||||
hana::make_pair(hana::type_c<end_tag>, last),
|
||||
hana::make_pair(hana::type_c<pass_tag>, &success),
|
||||
hana::make_pair(hana::type_c<val_tag>, global_nope),
|
||||
hana::make_pair(hana::type_c<attr_tag>, global_nope),
|
||||
@@ -141,8 +149,10 @@ namespace boost { namespace parser {
|
||||
hana::type_c<symbol_table_tries_tag>, &symbol_table_tries));
|
||||
}
|
||||
|
||||
template<typename ErrorHandler, typename Callbacks>
|
||||
template<typename Iter, typename ErrorHandler, typename Callbacks>
|
||||
inline auto make_context(
|
||||
Iter first,
|
||||
Iter last,
|
||||
bool & success,
|
||||
int & indent,
|
||||
ErrorHandler const & error_handler,
|
||||
@@ -151,6 +161,8 @@ namespace boost { namespace parser {
|
||||
symbol_table_tries_t & symbol_table_tries) noexcept
|
||||
{
|
||||
return hana::make_map(
|
||||
hana::make_pair(hana::type_c<begin_tag>, first),
|
||||
hana::make_pair(hana::type_c<end_tag>, last),
|
||||
hana::make_pair(hana::type_c<pass_tag>, &success),
|
||||
hana::make_pair(hana::type_c<val_tag>, global_nope),
|
||||
hana::make_pair(hana::type_c<attr_tag>, global_nope),
|
||||
@@ -166,10 +178,13 @@ namespace boost { namespace parser {
|
||||
}
|
||||
|
||||
template<
|
||||
typename Iter,
|
||||
typename ErrorHandler,
|
||||
typename Callbacks,
|
||||
typename GlobalState>
|
||||
inline auto make_context(
|
||||
Iter first,
|
||||
Iter last,
|
||||
bool & success,
|
||||
int & indent,
|
||||
ErrorHandler const & error_handler,
|
||||
@@ -178,6 +193,8 @@ namespace boost { namespace parser {
|
||||
symbol_table_tries_t & symbol_table_tries) noexcept
|
||||
{
|
||||
return hana::make_map(
|
||||
hana::make_pair(hana::type_c<begin_tag>, first),
|
||||
hana::make_pair(hana::type_c<end_tag>, last),
|
||||
hana::make_pair(hana::type_c<pass_tag>, &success),
|
||||
hana::make_pair(hana::type_c<val_tag>, global_nope),
|
||||
hana::make_pair(hana::type_c<attr_tag>, global_nope),
|
||||
@@ -859,8 +876,8 @@ namespace boost { namespace parser {
|
||||
rethrow_error_handler eh;
|
||||
nope n;
|
||||
symbol_table_tries_t symbol_table_tries;
|
||||
auto const context =
|
||||
make_context(success, indent, eh, n, symbol_table_tries);
|
||||
auto const context = make_context(
|
||||
first, last, success, indent, eh, n, symbol_table_tries);
|
||||
while (success) {
|
||||
skip_(
|
||||
hana::false_c,
|
||||
@@ -1370,6 +1387,8 @@ namespace boost { namespace parser {
|
||||
int trace_indent = 0;
|
||||
detail::symbol_table_tries_t symbol_table_tries;
|
||||
auto context = detail::make_context(
|
||||
first,
|
||||
last,
|
||||
success,
|
||||
trace_indent,
|
||||
error_handler,
|
||||
@@ -1415,6 +1434,8 @@ namespace boost { namespace parser {
|
||||
int trace_indent = 0;
|
||||
detail::symbol_table_tries_t symbol_table_tries;
|
||||
auto context = detail::make_context(
|
||||
first,
|
||||
last,
|
||||
success,
|
||||
trace_indent,
|
||||
error_handler,
|
||||
@@ -1470,6 +1491,8 @@ namespace boost { namespace parser {
|
||||
int trace_indent = 0;
|
||||
detail::symbol_table_tries_t symbol_table_tries;
|
||||
auto context = detail::make_context(
|
||||
first,
|
||||
last,
|
||||
success,
|
||||
trace_indent,
|
||||
error_handler,
|
||||
@@ -1519,6 +1542,8 @@ namespace boost { namespace parser {
|
||||
int trace_indent = 0;
|
||||
detail::symbol_table_tries_t symbol_table_tries;
|
||||
auto context = detail::make_context(
|
||||
first,
|
||||
last,
|
||||
success,
|
||||
trace_indent,
|
||||
error_handler,
|
||||
@@ -1568,6 +1593,8 @@ namespace boost { namespace parser {
|
||||
int trace_indent = 0;
|
||||
detail::symbol_table_tries_t symbol_table_tries;
|
||||
auto context = detail::make_context(
|
||||
first,
|
||||
last,
|
||||
success,
|
||||
trace_indent,
|
||||
error_handler,
|
||||
@@ -1615,6 +1642,8 @@ namespace boost { namespace parser {
|
||||
int trace_indent = 0;
|
||||
detail::symbol_table_tries_t symbol_table_tries;
|
||||
auto context = detail::make_context(
|
||||
first,
|
||||
last,
|
||||
success,
|
||||
trace_indent,
|
||||
error_handler,
|
||||
@@ -1649,6 +1678,8 @@ namespace boost { namespace parser {
|
||||
inline constexpr auto val_ = tag<detail::val_tag>;
|
||||
inline constexpr auto attr_ = tag<detail::attr_tag>;
|
||||
inline constexpr auto where_ = tag<detail::where_tag>;
|
||||
inline constexpr auto begin_ = tag<detail::begin_tag>;
|
||||
inline constexpr auto end_ = tag<detail::end_tag>;
|
||||
inline constexpr auto pass_ = tag<detail::pass_tag>;
|
||||
inline constexpr auto locals_ = tag<detail::locals_tag>;
|
||||
inline constexpr auto params_ = tag<detail::rule_params_tag>;
|
||||
@@ -1670,6 +1701,17 @@ namespace boost { namespace parser {
|
||||
{
|
||||
return *context[where_];
|
||||
}
|
||||
// TODO: Document that this is a lie within a skipper.
|
||||
template<typename Context>
|
||||
inline decltype(auto) _begin(Context const & context)
|
||||
{
|
||||
return context[begin_];
|
||||
}
|
||||
template<typename Context>
|
||||
inline decltype(auto) _end(Context const & context)
|
||||
{
|
||||
return context[end_];
|
||||
}
|
||||
template<typename Context>
|
||||
inline decltype(auto) _pass(Context const & context)
|
||||
{
|
||||
@@ -1696,6 +1738,42 @@ namespace boost { namespace parser {
|
||||
return *context[error_handler_];
|
||||
}
|
||||
|
||||
/** Report that the error described in `message` occurred at `location`,
|
||||
using the context's error handler. */
|
||||
template<typename Iter, typename Context>
|
||||
inline void _report_error(
|
||||
Context const & context, std::string_view message, Iter location)
|
||||
{
|
||||
return context[error_handler_]->diagnose(
|
||||
diagnostic_kind::error, message, context, location);
|
||||
}
|
||||
/** Report that the error described in `message` occurred at
|
||||
`_where(context).begin()`, using the context's error handler. */
|
||||
template<typename Context>
|
||||
inline void _report_error(Context const & context, std::string_view message)
|
||||
{
|
||||
return context[error_handler_]->diagnose(
|
||||
diagnostic_kind::error, message, context);
|
||||
}
|
||||
/** Report that the warning described in `message` occurred at `location`,
|
||||
using the context's error handler. */
|
||||
template<typename Iter, typename Context>
|
||||
inline void _report_warning(
|
||||
Context const & context, std::string_view message, Iter location)
|
||||
{
|
||||
return context[error_handler_]->diagnose(
|
||||
diagnostic_kind::warning, message, context, location);
|
||||
}
|
||||
/** Report that the warning described in `message` occurred at
|
||||
`_where(context).begin()`, using the context's error handler. */
|
||||
template<typename Context>
|
||||
inline void
|
||||
_report_warning(Context const & context, std::string_view message)
|
||||
{
|
||||
return context[error_handler_]->diagnose(
|
||||
diagnostic_kind::warning, message, context);
|
||||
}
|
||||
|
||||
/** TODO */
|
||||
template<unsigned int I>
|
||||
inline constexpr detail::param_t<I> _p = {};
|
||||
|
||||
@@ -23,6 +23,8 @@ namespace boost { namespace parser {
|
||||
struct val_tag;
|
||||
struct attr_tag;
|
||||
struct where_tag;
|
||||
struct begin_tag;
|
||||
struct end_tag;
|
||||
struct pass_tag;
|
||||
struct locals_tag;
|
||||
struct rule_params_tag;
|
||||
|
||||
Reference in New Issue
Block a user