2010/4/16 Michele Caini <michele.caini@gmail.com>
Hi all,
someone can explain to me how to use, if it's possible, on_error error
handler? I'd like to throw an exception reporting error data, because
I'm using spirit in a Qt-based application, and my idea is to catch
exception on upper level to pop-up a messagebox or something like that.

I start from documentation example, here:

on_error<fail>
(
 xml
 , std::cout
   << val("Error! Expecting ")
   << _4                               // what failed?
   << val(" here: \"")
   << construct<std::string>(_3, _2)   // iterators to error-pos, end
   << val("\"")
   << std::endl
);

Trying several possible solution, no one compiles fine. I don't know,
really, what I have to do, so please help me!! :-)

Thanks in advance,
Michele


Hi, ok, solution found.
Please, tell me if it's correct or there is a better one.

Code is like this:


template < typename It >
struct crc_parser
  : boost::spirit::qi::grammar<
        It, ::client::circuit(),
        boost::spirit::qi::ascii::space_type
      >
{

  typedef
  boost::spirit::qi::ascii::space_type
  space_type;

  crc_parser(std::ostream& err): crc_parser::base_type(circ, ".crc")
  {
    //   [...]

    qi::on_error<qi::fail>
      (circ, err
        << val("Syntax error. Expecting ")
        << _4
        << val(" here: \"")
        << construct<std::string>(_3, _2)
        << val("\"")
        << std::endl
      );
  }

  //   [...]

  boost::spirit::qi::rule<It, ::client::circuit(), space_type> circ;
};


In main function, I have:


  std::stringstream ss;
  while(stream_.good())
    ss << stream_.get();

  std::string crc = ss.str();
  std::string::const_iterator iter = crc.begin();
  std::string::const_iterator end = crc.end();

  ::client::circuit c;
  std::ostringstream oss;
  ::crc_parser<std::string::const_iterator> g(oss);
  bool r = boost::spirit::qi::phrase_parse(iter, end,
    g, boost::spirit::qi::ascii::space, c);

  if(!r || iter != end) {

    typedef
    boost::error_info<struct tag_what, std::string>
    what;

    sapecng::stream_read_error e;
    e << what(oss.str());

    throw e;

  }

etc.
What about? It seems to work fine, that sounds good.

Bye bye.