Boost logo

Boost Users :

Subject: Re: [Boost-users] Spirit and on_error
From: Michele Caini (michele.caini_at_[hidden])
Date: 2010-04-16 08:45:14


2010/4/16 Michele Caini <michele.caini_at_[hidden]>

> 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.



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net