3

I'm implementing a production rule for an if function:

qi::rule<Iterator, ascii::space_type, double(void)> f_if;
f_if = qi::ascii::string("if")
            >> qi::char_('(')
            >> (comparator >> ',' >> expression >> ',' >> expression) [qi::_val = boost::phoenix::bind(&Grammar<Iterator>::function_if, this, qi::_1, qi::_2, qi::_3)]
            >> qi::char_(')')
            ;

with expression and comparator declared as

qi::rule<Iterator, ascii::space_type, double(void)> expression;
qi::rule<Iterator, ascii::space_type, bool(void)> comparator;

and the binding function has the prototype

 double function_if(bool comparator, double left, double right);

Is there something I can do so that only one expression is evaluated, according to the value of the comparator?

P45 Imminent
  • 8,319
  • 4
  • 35
  • 78

2 Answers2

5

Use boost::phoenix::if_else which is an actor formulation of the C++ ternary operator:

>> (comparator >> ',' >> expression >> ',' >> expression) [qi::_val = boost::phoenix::if_else(qi::_1, qi::_2, qi::_3)]

(with all other lines of code as they were).

This means that only one of qi::_2 and qi::_3 will be evaluated.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
3

Of course you can! Nothing even says anything is evaluated.

So, you parse the the AST (Abstract Syntax Tree) for the complete input fragment, and when evaluating you skip the part that isn't applicable.

So, the key, as in many many cases, is to separate concerns. Compiler/interpreter design becomes orders of magnitude simpler to do right if you separate the parsing from the other stages (like evaluation, or in the case of a compiler, simplification, transformation and code generation).

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
sehe
  • 374,641
  • 47
  • 450
  • 633
  • So should I drop `function_if` altogether and so something with the ternary directly in the semantic action? – P45 Imminent Jun 11 '14 at 07:31
  • @YogiBear To be honest, I'd say the opposite. I'd say: **[try to do nothing in the semantic action](http://stackoverflow.com/questions/8259440/boost-spirit-semantic-actions-are-evil/8259585#8259585)** because it's simply too early to tell what needs to be done (think of backtracking rules, as well...). It's also more efficient if you evaluate similar expressions more than once for different inputs, and it reduces complexity by separating responsibilities. – sehe Jun 11 '14 at 08:10