I would like to add an exponential operator to the grammar of the expression represented in the Boost spirit samples .
The BNF grammar is as follows: (see this answer, for example: "An explicit grammar for the exposure operation" )
E -> E + T | E - T | T T -> T * F | T / F | X X -> X ^ Y | Y Y -> i | (E)
which I translated into Boost spirit as follows:
template <typename Iterator> struct calculator : qi::grammar<Iterator, ascii::space_type> { calculator() : calculator::base_type(expression) { qi::uint_type uint_; expression = term >> *( ('+' >> term [&do_add]) | ('-' >> term [&do_subt]) ) ; term = factor >> *( ( '*' >> factor [&do_mult]) | ('x' >> factor [&do_mult]) | ('/' >> factor [&do_div]) ); factor= expo >> *( '^' >> expo [&do_power]); expo = uint_ [&do_int] | '(' >> expression >> ')' | ('-' >> expo[&do_neg]) | ('+' >> expo) ; } qi::rule<Iterator, ascii::space_type> expression, term, factor, expo; };
The problem is that the ^ operator in this case is left associative, i.e. 2 ^ 3 ^ 4 incorrectly parsed as (2 ^ 3) ^ 4 instead of 2^ (3 ^ 4) .
How can I rewrite the grammar so that ^ becomes the correct associative? Obviously, the Klein star that I used in the definition of factor is incorrect. What is the method for translating grammar into Spirit code? There seems to be a way to move from left-factorized grammar to the realization of the Spirit, but I can't see it right away.
In a more formal form, the Spirit code looks like this (before I tried to add an exponent):
E = T ( +T | -T ) * T = F ( xF | /F ) * F = int | ( E ) | +F | -F
and left-factorized grammar
E = TE' E' = +TE' | -TE' | epsilon T = FT' T' = *FT' | /FT' | epsilon F = ( E ) | int | +F | -F