I'm trying to write a parser with Spirit X3, but I'm not very far, because I get a compilation error that I can not understand. I think I know that the compiler is complaining, but I donβt understand why this is worrying. The following code compiles (clang 3.9, Boost 1.62.0) and works. (I understand that it is poorly structured and that there are built-in parsers for persistent ones, I'm just trying to demonstrate the problem.)
#define BOOST_SPIRIT_X3_DEBUG #include <iostream> #include <boost/spirit/home/x3.hpp> using namespace std; namespace x3 = boost::spirit::x3; namespace lang { using namespace x3; struct Constant { }; rule<class constant_id, Constant> const constant = "constant"; auto const integer_literal = -char_('-') >> +digit; auto const float_literal = -char_('-') >> +digit >> -(char_('.') >> *digit); auto const constant_def = (integer_literal)[([](auto &ctx) { _val(ctx) = Constant(); })]; BOOST_SPIRIT_DEFINE(constant); } int main(int argc, char *argv[]) { string s("3.14159"); if (x3::phrase_parse(s.begin(), s.end(), lang::constant, x3::space)) { cout << "Ok!"; } else { cout << "Error!"; } return 0; }
However, if I change the constant_def to use float_literal instead of integer_literal:
auto const constant_def = (float_literal)[([](auto &ctx) { _val(ctx) = Constant(); })];
I am starting to get a compilation error.
sequence.hpp:143:9: error: static_assert failed "Attribute does not have the expected size." static_assert( ^
Looking at the source, I see a message:
I think the error is due to the presence of an optional float_literal in the definition. I believe the integer_literal attribute integer_literal is something like vector<char> , but that the optional float_literal attribute float_literal will be something like tuple<vector<char>, optional<vector<char>>> ? And somewhere, I'm trying to get this to be a string or something else, and it fails because it is trying to convert a 2-tuple to a 1-tuple. I suspect the solution is to wrap the definition of float_literal in raw[] , to get the base string I need instead. But since this is my first X3 parser, I want to understand why the compiler raises this error, so I can diagnose it if it appears in a different context.
I really don't understand why the compiler cares about the float_literal type. I applied a semantic action that generates an instance of Constant, which is a constant rule attribute type, without reference to the float_literal attribute, so why does the compiler not refer to the float_literal attribute at float_literal ? Where is he trying to perform the assignment of an uneven sequence and for what purpose?
Thanks!