Search code examples
c++error-handlingboost-spiritboost-spirit-qi

Boost.Spirit, Nabialek trick and error handling


Is it possible to combine "generic" error handling (like it's given in the tutorial) with Nabialek trick somehow? Like this:

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

start = *(keyword[_a = _1] > lazy(*_a));

some_other_rule.name("other rule's name");
...

Now, when some_other_rule is lazy-called and fails, the error message says that "lazy" was expected verbatim, and not "other rule's name" (which I need). Is it supposed to work that way and I'm simply mistaken somewhere else, or there are some other specific tricks involved?


Solution

  • Okay, I've worked it out (post it here for someone who hits the issue):

    some_other_rule and other rules whose pointers are selected via the keyword parser should start with qi::eps > ....

    That is because lazy is a parser itself, and when the invoked parser fails, lazy gets rolled back to try other possible branches. And since the only expectation is the one preceeding it (... > lazy()), expectation failure is raised against lazy. So, what we do is add another expectation closer to the actual error.