Spirit X3, Is this error handling approach useful?

前端 未结 2 964
南笙
南笙 2020-12-10 21:20

After reading the the Spirit X3 tutorial on error handling and some experimentation. I was drawn to a conclusion.

I believe there is some room for improvement on the

2条回答
  •  星月不相逢
    2020-12-10 21:54

    Now for expression a I cannot use expect[] or operator>, as other alternatives might be valid. I could be wrong but I think X3 requires me to spell out alternate wrong expressions that can match and if they match they can throw x3::expectation_failure which is cumbersome.

    That's simple:

    const auto main_rule__def = x3::expect [
     a |
     b |
     c ];
    

    Or, even:

    const auto main_rule__def = x3::eps > (
     a |
     b |
     c );
    

    If the answer is no, I would like to present my idea to provide a reasonable solution for this. I believe I would need a new parser directive for that. What should this directive do? It should call the attached semantic action when the parse fails instead.

    The existing x3::on_error feature already knows how to do this. Mind you: it's a little bit intricate, but on the same merit it's also pretty flexible.

    Basically what it requires is for you to implement a static interface on the ID type (x3::rule, likely main_rule_class in your chosen convention). There are compiler examples in the repository that show how to use it.

    Side note: there's both on_success and on_error using this paradigm

    The on_error member will be called on a default-constructed copy of the ID type, with the parameters ID().on_error(first, last, expectation_failure_object, context).

    const auto main_rule__def =
    (
     neg_sa[a][a_sa] |
     neg_sa[b][b_sa] |
     neg_sa[c][c_sa] );
    

    To be honest, I think you're paving over your confusion here. What good does it give that you have 3 separate error actions? How would you decide which error happened?

    Really there only two possibilities:

    • Either you DO know that a specific branch was required AND it failed (that's an expectation failure and you can by definition code that as an expectation point inside one of a, b or c).
    • Or you DO NOT know which branch was implied (say, when branches can start out with similar productions and they failed inside those). In that case, nobody can ever tell which error handler should be invoked, so having more than one is beside the point.

      Actually the correct thing to do is fail the main_rule at the higher level and it would mean "none of the possible branches succeeded".

      This is the expect[ a | b | c ] way of dealing with it.

提交回复
热议问题