0

I have rather complicated expression parser with strict type checking. So my expression rule declared to return effective type-index. Like that:

qi::rule < Iterator, type_index_t, skipper<Iterator>> 
    set_expression, expression, single_expression;

Now I have chaining multiple expression by rule:

expression = ((single_expression|set_expression) >> -(expression) )[
                // following looks redundant
                qi::_val = boost::phoenix::if_else(qi::_2, *qi::_2, qi::_1)
            ]
            | qi::lit('(') >> expression >> ')'
            ;

Without explicit semantic action with if_else I got wrong result of type of first entry instead of the last one.

So my question: is there better way to obtain correct expression type that equals to last item in sequence?

cigien
  • 57,834
  • 11
  • 73
  • 112
Dewfy
  • 23,277
  • 13
  • 73
  • 121
  • 1
    Are you really wanting to competely ignore the result/type of (single_expression|set_expression)? Why not simply `-qi::omit[single_expression|set_expression] >> ('(') >> expression >> ')')` then? – sehe Apr 21 '21 at 08:52
  • if you didn't want to ignore that part, then obviously the semantic action is not redundant: it's required to transform your `tuple>` into a single `type_index_t` based on your specific business logic. There's no way the parser could "magically guess" that logic. – sehe Apr 21 '21 at 08:54
  • @sehe I don't ignore `single_expression|set_expression` result - they are managed in other part of the grammar (for example on single_expression I have `int + double=double`) but total result really depends of right-most entry. – Dewfy Apr 21 '21 at 09:45
  • So, you have my answer. Also, are you using a separate parser instance just to get the type? It sure looks like separation of concerns would help. Parser(input) -> AST; then get_type(AST) -> type_index_t, and e.g. evaluate(AST) -> variant_value_t, simplify(AST) -> AST etc. – sehe Apr 21 '21 at 10:33
  • @sehe well, I have AST but it is hidden behind the scene since I have big payload on creation of result, so no way to declare `qi::rule < Iterator, Expression...`. Can you please convert your comment to the answer, so I could appreciate it. – Dewfy Apr 21 '21 at 17:46
  • I'm confused. You say your AST is heavy ("big payload") on "creation of result", yet the rule doesn't create that AST, but rather extracts the "type_index_t" from the last sub-expression only? Is `type_index_t` part of that heavy AST or not? I was assuming it's not. Are you parsing things twice? Is there some more code you can show? As it is is, I have no idea what part of my comments you think I should convert to an answer. – sehe Apr 21 '21 at 19:49
  • @sehe I have semantic action that pushes commands to "singleton" AST. Each command has strict definition of expected input type_index's and output type as well. Each `single_expression` is a key registered in `qi::symbols`. So generation of Commands string managed by singleton, while grammar only check syntax and pushes commands – Dewfy Apr 22 '21 at 06:39
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/231456/discussion-between-sehe-and-dewfy). – sehe Apr 22 '21 at 11:44

0 Answers0