Something seems to have changed in spirit::x3 that breaks my fancy little asdl parser. It worked just fine when I ported it over from Qi (after the initial x3 bugfixes made their way into fedora) but now fails with:
/usr/include/boost/spirit/home/x3/operator/detail/sequence.hpp:143:9: error: static assertion failed: Attribute does not have the expected size.
#include <boost/spirit/home/x3.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include "asdl.h"
typedef boost::variant<asdl::ast::Product, asdl::ast::Sum> type_variant;
typedef std::vector<asdl::ast::Field> field_vec;
BOOST_FUSION_ADAPT_STRUCT(
asdl::ast::Module,
(std::string, id)
(std::vector<asdl::ast::Type>, dfns))
BOOST_FUSION_ADAPT_STRUCT(
asdl::ast::Type,
(std::string, name)
(type_variant, value))
BOOST_FUSION_ADAPT_STRUCT(
asdl::ast::Field,
(std::string, type)
(boost::optional<char>, flag)
(boost::optional<std::string>, name))
BOOST_FUSION_ADAPT_STRUCT(
asdl::ast::Constructor,
(std::string, name)
(boost::optional<field_vec>, fields))
BOOST_FUSION_ADAPT_STRUCT(
asdl::ast::Sum,
(std::vector<asdl::ast::Constructor>, types)
(boost::optional<field_vec>, attributes))
BOOST_FUSION_ADAPT_STRUCT(
asdl::ast::Product,
(field_vec, fields))
namespace asdl
{
namespace x3 = boost::spirit::x3;
namespace ascii = boost::spirit::x3::ascii;
x3::rule<class module, ast::Module > const module = "module";
x3::rule<class definitions, ast::Type > const definitions = "definitions";
x3::rule<class type, type_variant > const type = "type";
x3::rule<class fields, field_vec > const fields = "fields";
x3::rule<class field, ast::Field > const field = "field";
x3::rule<class product, ast::Product > const product = "product";
x3::rule<class sum, ast::Sum > const sum = "sum";
x3::rule<class constructor, ast::Constructor> const constructor = "constructor";
auto const alpha = '_' | ascii::upper | ascii::lower;
auto const alpha_num = alpha | ascii::digit;
auto const typ_id = x3::lexeme[ascii::lower >> *alpha_num];
auto const con_id = x3::lexeme[ascii::upper >> *alpha_num];
auto const id = typ_id | con_id;
auto const module_def = "module" >> id >> '{' >> *definitions >> '}';
auto const definitions_def = typ_id >> '=' >> type;
auto const type_def = product | sum;
auto const product_def = fields;
auto const sum_def = constructor % '|' >> -("attributes" >> fields);
auto const constructor_def = con_id >> -fields;
auto const fields_def = '(' >> field % ',' >> ')';
auto const field_def = typ_id >> -(ascii::char_('?') | ascii::char_('*')) >> -id;
BOOST_SPIRIT_DEFINE(module, definitions, type, product, sum, constructor, fields, field);
bool parse(const std::string &input, ast::Module &mod) {
std::string::const_iterator iter = input.begin();
std::string::const_iterator end = input.end();
return (x3::phrase_parse(iter, end, module, ascii::space, mod) && iter == end);
}
} //namespace asdl
Note: BOOST_FUSION_ADAPT_STRUCT is a straight wrapper around bare structs with exactly the same fields.
I searched all (2) other references to "Attribute does not have the expected size" but don't quite understand the problem enough to even begin to fix the code -- part of the problem is the program generates the ast that it parses into (eat your own dogfood as they say) so without knowing why the assertion fails I don't know which to modify, the parser or the code that outputs the ast structs.
And here I thought that yak was done shaved...