问题
What is the logic under using boost::spirit::x3::position_tagged
as base class for some AST nodes (how to choose which should be tagged, e.g. for C-like language?) and other constructions, used in rule ID definition, like:
struct error_handler_tag;
struct error_handler_base
{
template< typename Iterator, typename Exception, typename Context >
x3::error_handler_result
on_error(Iterator & /*first*/, Iterator const & /*last*/,
Exception const & x, Context const & context)
{
std::string message_ = "Error! Expecting: " + x.which() + " here:";
auto & error_handler = x3::get< error_handler_tag >(context).get();
error_handler(x.where(), message_);
return x3::error_handler_result::fail;
}
};
struct annotation_base
{
template< typename T, typename Iterator, typename Context >
void
on_success(Iterator const & first, Iterator const & last,
T & ast, Context const & context)
{
auto & error_handler = x3::get< error_handler_tag >(context).get();
error_handler.tag(ast, first, last);
}
};
// ...
error_handler_type error_handler(beg, end, std::cerr);
auto const parser_ = x3::with< error_handler_tag >(std::ref(error_handler))[grammar];
// ...
?
In case of erroneous input (grammar not match) this part of code does nothing (even in case of simpliest grammar, which should recognize an identifiers) - not printing an error mesage.
回答1:
A gramatically correct parse does not mean the AST can be succesfully evaluated as well. Think of a grammar defining some evaluator that can evaluate math expressions like "3+4/(5-5)". It will parse just fine, but during the AST evaluation you may want to raise an error on the "5-5" as an argument to a division. For that, it is handy to have the position of the element you are complaining about.
来源:https://stackoverflow.com/questions/25778915/error-handling-and-annotation-in-boost-spirit-x3