I'm basing my app off this example and getting the exact same results. For some reason, the contents of the input string are all parsed into the fusion struct 'comments', and nothing is parsed into the fusion struct 'numbers'. So not sure where I'm going wrong here.
namespace client {
namespace ast {
struct number {
int num1;
int num2;
};
struct comment {
std::string text;
bool dummy;
};
struct input {
std::vector<comment> comments;
std::vector<number> numbers;
};
}
}
BOOST_FUSION_ADAPT_STRUCT(client::ast::comment, text, dummy)
BOOST_FUSION_ADAPT_STRUCT(client::ast::number, num1, num2)
BOOST_FUSION_ADAPT_STRUCT(client::ast::input, comments, numbers)
namespace client {
namespace parser {
namespace x3 = boost::spirit::x3;
using namespace x3;
x3::attr_gen dummy;
typedef std::string::const_iterator It;
using namespace x3;
auto const comment = *(char_ - eol) >> dummy(false);
auto const number = int_ >> int_;
auto lines = [](auto p) { return *(p >> eol); };
auto const input =
lines(comment) >>
lines(number);
}
}
int main()
{
namespace x3 = boost::spirit::x3;
std::string const iss("any char string here\n1 2\n");
auto iter = iss.begin(), eof = iss.end();
client::ast::input types;
bool ok = parse(iter, eof, client::parser::input, types);
if (iter != eof) {
std::cout << "Remaining unparsed: '" << std::string(iter, eof) << "'\n";
}
std::cout << "Parsed: " << (100.0 * std::distance(iss.begin(), iter) / iss.size()) << "%\n";
std::cout << "ok = " << ok << std::endl;
// This range loop prints all contents if input.
for (auto& item : types.comments) { std::cout << "comment: " << boost::fusion::as_deque(item) << "\n"; }
// This loop prints nothing.
for (auto& item : types.numbers) { std::cout << "number: " << boost::fusion::as_deque(item) << "\n"; }
}
My larger application does the same with a large input file and several more AST's, yet it would seem all my examples are consumed by the comment parser.
Here's the complete running example.
http://coliru.stacked-crooked.com/a/f983b26d673305a0
Thoughts?
You took the grammar idea from my answer here: X3, how to populate a more complex AST?
There it worked because the line formats are not ambiguous. In fact the "variant" approach you had required special attention, and I noted that in this bullet:
- departments need to be ordered before teams, or you get "team" matched instead of departments
The same kind of ambiguity exists in your grammar. *(char_ - eol)
matches "1 2"
just fine, so obviously it is added as a comment. You will have to disambiguate the grammar or somehow force the switch to "parse number lines now" mode.
If you wholly don't care what precedes the number lines, just use x3::seek [ lines(number) ]
.