3

I'm trying to extend an existing use of Boost::spirit implementing a configuration language (with Boost 1.55.0).

If a rule or token fails to match, then the Boost system happily takes care of throwing an expectation_failure exception that I can use to complain about where in the nested set of configuration files the error was encountered.

However, there are several clauses where a semantic action consists of something like:

[ phx::bind(map_insert_table, qi::_1, ref(tbl), _val) ]

where map_insert_table() is a function I define which might have an exception condition. If I simply throw my own C++ exception I will abort processing of the file with a meaningful error message, but I will have no way to tell the user the location of their error. If I simply set _pass to false per boost spirit semantic action parameters, then the user will know where the error occurred, but not be given the information we have as to what was actually wrong.

I appreciate the information in that linked question regarding the context, but I don't see how it can help me here, nor how I would access it from the semantic action as phrased above.

I also appreciate that I might be told I'm not using the system in the best way -- that may be true, and I can make incremental changes, but rewriting our whole use of Boost::spirit would be very much a solution of last resort.

All answers appreciated. If more information is needed for my question to be answered (this is my first post after years of lurking) I will certainly try to provide it.

Community
  • 1
  • 1
ChissG
  • 33
  • 3
  • I'd personally consider the context object an implementation detail and don't recommend piggy-backing on it - probably just because it confuses me (and it's not part of public documentation AFAIK) – sehe Jul 30 '14 at 19:20

1 Answers1

1

You are already using references inside the phoenix actor. You can use the same method to store error information somewhere "out-of-band".

Alternatively, you might store optional diagnostics information as part of the attribute type.

sehe
  • 374,641
  • 47
  • 450
  • 633
  • True @sehe (and thank you for your interest), but I was hoping there was a mechanism within the Boost system to do this already. It's cumbersome to pass the information all the way back up to the top-level parser object which can turn the error location into something meaningful for the user, but it is possible and I will do just that if there is no, "nice" way of doing it within the Boost::spirit framework. – ChissG Jul 30 '14 at 20:13
  • Nicer than what? Nicer than `qi::locals`? Nicer than `phx::ref(this->grammer_member)`? Nicer than `qi::on_error`? Nicer than `iter_pos`? I'm not sure where the "It's cumbersome" peaks in your experience. For me expectation points are plenty fine. I can get the position out of the position iterators from an `expectation_failure` exception. I don't mind putting a string containing the reason into a grammar instance variable. – sehe Jul 30 '14 at 21:02
  • By the way, this question reminded me of [this older question](http://stackoverflow.com/a/19240806/85371); That's a weak match though. Consider this for background reading: **[access position iterator from semantic actions](http://stackoverflow.com/questions/19612657/boostspirit-access-position-iterator-from-semantic-actions/19613827#19613827)**. It's my recommended solution for passing source position down with the Ast nodes. – sehe Jul 30 '14 at 21:19