Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x3::eps with a semantic action breaks parsing into structs #659

Closed
syyyr opened this issue Mar 8, 2021 · 3 comments
Closed

x3::eps with a semantic action breaks parsing into structs #659

syyyr opened this issue Mar 8, 2021 · 3 comments

Comments

@syyyr
Copy link

syyyr commented Mar 8, 2021

Hi, I'm trying to get rid of fusion stuff in my single-element structs as suggested in #463.
While doing that, I found a bug with semantic actions, where the struct doesn't get correctly filled with the value. This is how to reproduce.

#include <iostream>
#include <boost/spirit/home/x3.hpp>

namespace x3 = boost::spirit::x3;

struct number {
  int value;
  number& operator=(const int data) {
      this->value = data;
      return *this;
  }
};

auto doSideEffects = x3::eps[([] (auto& ctx) {
    // do some stuff...
})];

auto wrappedDoSideEffects = x3::rule<class Rule, x3::unused_type>{} = doSideEffects;

auto my_rule = x3::rule<class my_class, number>{} = doSideEffects > x3::int32;

int main(int argc, char* argv[])
{
    std::string input = "235";
    number out;
    auto it = input.begin();
    auto res = x3::parse(it, input.end(), my_rule, out);
    // This doesn't print 235, because doSideEffects breaks the parser.
    // If I swap doSideEffects with wrappedDoSideEffects, it works again.
    std::cout << "out.arg = " << out.value << "\n";

    return 0;
}

My operator= actually never gets called. I'm not sure I implemented it correctly. Is this really a bug or am I doing something wrong?
I have also tried adding another member into the struct and use BOOST_FUSION_ADAPT_STRUCT and the bug is still there: https://gist.github.com/syyyr/94f7f9a0b65e8d4a81eb7a55be8e62ff

Boost version: 1.75.0

@djowel
Copy link
Member

djowel commented Mar 8, 2021

Semantic actions on a rule definition inhibit automatic attribute propagation. See:

https://stackoverflow.com/questions/33929849/boost-spirit-x3-ast-not-working-with-semantic-actions-when-using-separate-rule-d

@syyyr
Copy link
Author

syyyr commented Mar 8, 2021

So, the function of operator%= is to automatically propagate attributes even if I'm using semantic actions?

@syyyr
Copy link
Author

syyyr commented Mar 8, 2021

@syyyr syyyr closed this as completed Mar 8, 2021
jktjkt pushed a commit to CESNET/netconf-cli that referenced this issue Mar 8, 2021
There are actually two fixes: the first one is a direct fix to the
linked issue. The attribute of the rule for switch was wrong. I'm not
sure how I missed that, but OK, now we have tests.

The other bug:
For some reason, the completion generator prevented the symbol table
parser from running and the value inside the resulting switch_ was
undefined. Asserting the attribute of the completion generator seems to
solve the issue.

I thought this would have something to do with the fact that I'm using
single member fusion structs. However, the bug still persisted even when
converting them into non-fusion structs (as suggested in the first
issue).

At some point, all single-member fusion structs should be converted into
non-fusion structs, but because it doesn't solve my problem, I won't be
doing it now.

Issue: boostorg/spirit#463
Issue: boostorg/spirit#659
Issue: https://tree.taiga.io/project/jktjkt-netconf-cli/issue/218
Change-Id: I364b32b76741c198808cc2b3c5027913162d0703
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants