4

boost::phoenix defines statement blocks using the operator "," (see boost phoenix block statements). I'm trying to use this construct in the semantic action part of a boost::spirit rule. However, it looks like only the last statement in the statement block is executed. Here is a minimal compilable example that shows the problem:

#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>

int main()
{
    using boost::spirit::qi::int_;
    using boost::phoenix::ref;
    using boost::spirit::qi::phrase_parse;
    using boost::spirit::ascii::space;

    int a = 0;
    int b = 0;

    const std::string s("1");
    bool f = phrase_parse(s.begin(),s.end(),
            int_[
                 ref(a)=1,
                 ref(b)=2
                ],
            space);
    std::cout << f << ": a=" << a << ", b=" << b << std::endl;
}

This program (using boost 1.52) prints

1: a=0, b=2

but I was expecting a=1, b=2. Is this how it is supposed to work? Why?

Thanks!

ildjarn
  • 62,044
  • 9
  • 127
  • 211
mvc
  • 653
  • 1
  • 5
  • 9

1 Answers1

5

In the light of the fact that compiletimes are never going to be quick using Spirit, I'd suggest sticking to the 'highlevel includes' for utility libraries:

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>

int main()
{
    namespace qi = boost::spirit::qi;

    int a = 0, b = 0;

    const std::string s("1");
    bool f = qi::phrase_parse(s.begin(),s.end(),
            qi::int_[
                 boost::phoenix::ref(a)=1,
                 boost::phoenix::ref(b)=2
                ],
            qi::space);
    std::cout << f << ": a=" << a << ", b=" << b << std::endl;
}

Likewise, I usually suggest boost/fusion/adapted.hpp over boost/fusion/adapted/struct.hpp e.a., or boost/range/algorithm.hpp.

Your mileage may vary, but TU's defining Spirit parsers aren't usually the point to optimize for compile times in my projects.

sehe
  • 374,641
  • 47
  • 450
  • 633