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

Nested aggregate structures do not work #50

Closed
akrzemi1 opened this issue Jan 5, 2024 · 4 comments
Closed

Nested aggregate structures do not work #50

akrzemi1 opened this issue Jan 5, 2024 · 4 comments

Comments

@akrzemi1
Copy link
Member

akrzemi1 commented Jan 5, 2024

Sorry, one more. The following case where we have an indirectly nested aggregate doesn't compile:

#include <boost/parser/parser.hpp>
#include <vector>

struct X {
  char a;
  int b;
};

struct Y {
  std::vector<X> x;
  int c;
};

int main()
{
  namespace bp = boost::parser;
  auto parse_x = bp::char_ >> bp::int_;
  auto parse_y = +parse_x >> bp::int_;

  Y y;
  auto b = bp::parse("d 3 4", parse_y, bp::ws, y);
}

The Boost.Spirit analogue compiles fine:

#include <boost/fusion/adapted/struct/adapt_struct.hpp>
#include <boost/spirit/include/qi.hpp>

struct X {
  char a;
  int b;
};

struct Y {
  std::vector<X> x;
  int c;
};

BOOST_FUSION_ADAPT_STRUCT(X, a, b);
BOOST_FUSION_ADAPT_STRUCT(Y, x, c);

int main()
{
  namespace bp = boost::spirit::qi;
  auto parse_x = bp::char_ >> bp::int_;
  auto parse_y = +parse_x >> bp::int_;

  Y y;
  std::string input = "d 3 4";
  auto begin = input.begin();
  bool b = bp::phrase_parse(begin, input.end(), parse_y, bp::ascii::space, y);
}
@tzlaine
Copy link
Collaborator

tzlaine commented Jan 6, 2024

Don't be sorry! I appreciate the early review. I'll investigate this this weekend.

@tzlaine
Copy link
Collaborator

tzlaine commented Jan 6, 2024

Even worse, this also does not work:

#include <boost/parser/parser.hpp>
#include <vector>

struct X {
  char a;
  int b;
};

struct SimplerY {
  X x;
  int c;
};

int main()
{
  namespace bp = boost::parser;
  auto parse_x = bp::char_ >> bp::int_;
  auto parse_y = parse_x >> bp::int_;

  SimplerY y;
  auto b = bp::parse("d 3 4", parse_y, bp::ws, y);
}

I have some work to do it seems.

@tzlaine
Copy link
Collaborator

tzlaine commented Jan 6, 2024

Ok, after thinking about this a bit, there's no bug with my "simplified" case above. When you write parse_x >> bp::int_ as the definition of parse_y, the sequence-parser parse_x combines with bp::int_, just as if you wrote it all on the same line. IOW, parse_y is equivalent to bp::char_ >> bp::int_ >> bp::int_. When you then try to parse that into an object of type Y, it has to map the three elements the parse expects onto the two data members of `Y.

@akrzemi1
Copy link
Member Author

akrzemi1 commented Jan 6, 2024

Correct. Boost.Spirit also rejects your simplified example.

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