Search code examples
boostboost-spiritboost-spirit-x3

Boost Spirit x3 parsing into a struct with single field


Im keep invistigate boost spirit examples, and collided with the following problem. (i think it was described somwhere like a bug in the code, but i may be wrong)

Simply: Parser didn build when try to pars into a struct with a single filed of type inherited from x3::variant.

Here is the part of code

struct operand : x3::variant<
        nil
      , unsigned int
      , std::string          
      , x3::forward_ast<expression>
    >
{
    using base_type::base_type;
    using base_type::operator=;
};
struct assign_return
{
    char sign;
    operand var;
};

which i parse as folows (of cource all it needed define correctly)

auto const areturn_def =
        lexeme["return" >> !(alnum | '_')] >> char_(':') >> expression >> ';';

This code worked correctly,

but if i dont wanna parse ':' and chaged everything according with (ofcource i do changes in BOOST_FUSION_ADAPT_STRUCT for this struct)

struct assign_return
{        
    operand var;
};
auto const areturn_def =
        lexeme["return" >> !(alnum | '_')] >> expression >> ';';

This code didnt build up with the foollowing error:

C:\Program Files\boost\boost\boost\spirit\home\x3\nonterminal\rule.hpp:113:  undefined reference to `bool client::parser::parse_rule<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::spirit::x3::context<boost::spirit::x3::skipper_tag, boost::spirit::x3::char_class<boost::spirit::char_encoding::ascii, boost::spirit::x3::space_tag> const, boost::spirit::x3::unused_type>, client::ast::assign_return>(boost::spirit::x3::rule<client::parser::expression_class, client::ast::expression, false>, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >&, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, boost::spirit::x3::context<boost::spirit::x3::skipper_tag, boost::spirit::x3::char_class<boost::spirit::char_encoding::ascii, boost::spirit::x3::space_tag> const, boost::spirit::x3::unused_type> const&, client::ast::assign_return&)'

If we look carefully at the error code and function it mention

template <typename Iterator, typename Context, typename Attribute_>    
bool parse(Iterator& first, Iterator const& last
      , Context const& context, unused_type, Attribute_& attr) const

We could see, that template parameters are correct, but argument list:

(rule, iterator, iterator, context, Attribute) 

It seems like a problem of undefined reference, but how?

Thanks for any help!


Solution

  • Yeah. This looks like unrelated to single-element sequences. Linker errors usually are :)

    You could probably employ the techniques demonstrated

    To find the culprit. If you post a full, minimal, "working" example we can help.