8

I made some tests using the spirit mini_c sample. Unfortunately it does not keep the operator precedence as expected:

int main()
{
    return 3 > 10 || 3 > 1;
}

evaluates to 0.

return (3 > 10) || (3 > 1);

returns 1

I tried to move the definition of "||" and "&&" to the very top in the constructor of

template <typename Iterator>
expression<Iterator>::expression(

but that does not change anything. How can that be fixed. I am using boost 1.3.38.

Nicolas Kaiser
  • 1,628
  • 2
  • 14
  • 26
RED SOFT ADAIR
  • 12,032
  • 10
  • 54
  • 92
  • I've never used Boost.Spirit, but I don't see how anything it defines could possibly make a difference here. You have nothing but primitives, and you can't overload the built in operators. – Dennis Zickefoose Aug 28 '10 at 15:42
  • I have another question considering this sample. Maybe you can help with that too ? http://stackoverflow.com/questions/3591533/implementing-not-in-boostspirit-mini-c – RED SOFT ADAIR Aug 28 '10 at 16:37

1 Answers1

7

Confirmed, that's a bug in the mini_c example related to operator precedence. I committed a fix to SVN, which will be available in Boost V1.45. Here is what I changed in the header file mini_cb.hpp:

old code:

equality_expr =
    relational_expr
    >> *(   ("==" > relational_expr     [op(op_eq)])
        |   ("!=" > relational_expr     [op(op_neq)])
        )
    ;

relational_expr =
    logical_expr
    >> *(   ("<=" > logical_expr        [op(op_lte)])
        |   ('<' > logical_expr         [op(op_lt)])
        |   (">=" > logical_expr        [op(op_gte)])
        |   ('>' > logical_expr         [op(op_gt)])
        )
    ;

logical_expr =
    additive_expr
    >> *(   ("&&" > additive_expr       [op(op_and)])
        |   ("||" > additive_expr       [op(op_or)])
        )
    ;

new code:

equality_expr =
    logical_expr
    >> *(   ("==" > logical_expr        [op(op_eq)])
        |   ("!=" > logical_expr        [op(op_neq)])
        )
    ;

logical_expr =
    relational_expr
    >> *(   ("&&" > relational_expr     [op(op_and)])
        |   ("||" > relational_expr     [op(op_or)])
        )
    ;

relational_expr =
    additive_expr
    >> *(   ("<=" > additive_expr       [op(op_lte)])
        |   ('<' > additive_expr        [op(op_lt)])
        |   (">=" > additive_expr       [op(op_gte)])
        |   ('>' > additive_expr        [op(op_gt)])
        )
    ;
hkaiser
  • 11,403
  • 1
  • 30
  • 35
  • Thanks a lot. I tried the same, but i forgot to modify the parameters inside the definitions. – RED SOFT ADAIR Aug 28 '10 at 16:28
  • 1
    Hello Hartmut. Today - 1 1/2 Years later i found out, that the code is still not correct: "==" and "&&" must be evaluated at last - AFTER "==" and "!=", not before. – RED SOFT ADAIR Feb 27 '12 at 15:38