Search code examples
c++boostboost-spiritboost-spirit-x3

Boost Spirit X3 local variables and getting the synthesized attribute


I'm trying to port a parser from Spirit V2 to X3. The overall experience is quite good but there are two problems.

The first one is that local variables are gone, which is quite inconvenient to me since I used them quite often to keep track of things. Hence I'm asking for something that would do the job of locals in V2.

The other one is best illustrated with this dummy example: I want to parse a comma separated list of integers into a vector<int>, but it should only parse when the list sums up to zero:

auto const int_list = rule<class int_list, vector<int>>("int_list")
    = int_ % ','
    >> eps(/* How to extract the attribute? */);

I'm stuck with the last checking here as I don't know how to get my hands on the vector<int> the rule is synthesizing.


Solution

  • I had the same findings!

    The trick with "locals" is to use the with<> directive.

    Because you give no usage scenario, I don't think it's worth coming up with examples, though you can search my answers for them*

    The trick with the second is to just use a semantic action (which can be a lambda) and assign _pass: Boost Spirit X3 cannot compile repeat directive with variable factor shows this too:

    auto zerosum = [](auto &ctx) { 
        auto& v = x3::_attr(ctx); 
        _pass(ctx) = std::accumulate(v.begin(), v.end(), 0) == 0;
    };