Boost Spirit X3:尝试解析A>时的链接器错误未使用的>一个适应的结构

时间:2017-06-23 12:51:47

标签: c++ boost boost-spirit boost-spirit-x3

我基于精灵x3 calc8 / calc9示例创建了一个解析器。 链接器错误(见下文)是使用以下定义时的结果:

const auto statement_def = expression > x3::eps > expression;

使用以下结构:

struct statement
{
    expression lhs;
    expression rhs;
};
// ...
BOOST_FUSION_ADAPT_STRUCT(ast::statement, lhs, rhs)

但以下工作没有问题:

const auto statement_def = expression > expression;

这也有效:

const auto statement_def = expression > expression > x3::eps;

这也有效: 将statement结构更改为struct statement : std::list<expression> {}可以编译并运行。

Compound Attribute Rules应该使其等效:

  • a: A, b: Unused --> (a >> b): A
  • a: A, b: A --> (a >> b): vector<A>

为什么未使用的属性解析器会导致问题?

这是链接器错误我得到:

statement.cpp.o: In function `bool boost::spirit::x3::rule<parser::expression_class, ast::expression, false>::parse<__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::error_handler_tag, std::reference_wrapper<boost::spirit::x3::error_handler<__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> >, boost::fusion::iterator_range<boost::fusion::basic_iterator<boost::fusion::struct_iterator_tag, boost::fusion::random_access_traversal_tag, ast::statement, 0>, boost::fusion::basic_iterator<boost::fusion::struct_iterator_tag, boost::fusion::random_access_traversal_tag, ast::statement, 1> > >(__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::error_handler_tag, std::reference_wrapper<boost::spirit::x3::error_handler<__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&, boost::spirit::x3::unused_type, boost::fusion::iterator_range<boost::fusion::basic_iterator<boost::fusion::struct_iterator_tag, boost::fusion::random_access_traversal_tag, ast::statement, 0>, boost::fusion::basic_iterator<boost::fusion::struct_iterator_tag, boost::fusion::random_access_traversal_tag, ast::statement, 1> >&) const':
statement.cpp:(.text._ZNK5boost6spirit2x34ruleIN6parser16expression_classEN3ast10expressionELb0EE5parseIN9__gnu_cxx17__normal_iteratorIPKcNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEENS1_7contextINS1_17error_handler_tagEKSt17reference_wrapperINS1_13error_handlerISJ_EEENSK_INS1_11skipper_tagEKNS1_10char_classINS0_13char_encoding5asciiENS1_9space_tagEEENS1_11unused_typeEEEEENS_6fusion14iterator_rangeINS11_14basic_iteratorINS11_19struct_iterator_tagENS11_27random_access_traversal_tagENS5_9statementELi0EEENS13_IS14_S15_S16_Li1EEEEEEEbRT_RKS1A_RKT0_SY_RT1_[_ZNK5boost6spirit2x34ruleIN6parser16expression_classEN3ast10expressionELb0EE5parseIN9__gnu_cxx17__normal_iteratorIPKcNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEENS1_7contextINS1_17error_handler_tagEKSt17reference_wrapperINS1_13error_handlerISJ_EEENSK_INS1_11skipper_tagEKNS1_10char_classINS0_13char_encoding5asciiENS1_9space_tagEEENS1_11unused_typeEEEEENS_6fusion14iterator_rangeINS11_14basic_iteratorINS11_19struct_iterator_tagENS11_27random_access_traversal_tagENS5_9statementELi0EEENS13_IS14_S15_S16_Li1EEEEEEEbRT_RKS1A_RKT0_SY_RT1_]+0x37): undefined reference to `bool 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::error_handler_tag, std::reference_wrapper<boost::spirit::x3::error_handler<__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> >, boost::fusion::iterator_range<boost::fusion::basic_iterator<boost::fusion::struct_iterator_tag, boost::fusion::random_access_traversal_tag, ast::statement, 0>, boost::fusion::basic_iterator<boost::fusion::struct_iterator_tag, boost::fusion::random_access_traversal_tag, ast::statement, 1> > >(boost::spirit::x3::rule<parser::expression_class, 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::error_handler_tag, std::reference_wrapper<boost::spirit::x3::error_handler<__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&, boost::fusion::iterator_range<boost::fusion::basic_iterator<boost::fusion::struct_iterator_tag, boost::fusion::random_access_traversal_tag, ast::statement, 0>, boost::fusion::basic_iterator<boost::fusion::struct_iterator_tag, boost::fusion::random_access_traversal_tag, ast::statement, 1> >&)'
collect2: error: ld returned 1 exit status

我怀疑它与boost::fusion::iterator_range<boost::fusion::basic_iterator<boost::fusion::struct_iterator_tag, boost::fusion::random_access_traversal_tag, ast::statement, 0>, boost::fusion::basic_iterator<boost::fusion::struct_iterator_tag, boost::fusion::random_access_traversal_tag, ast::statement, 1> >有关。

以下是代码:https://wandbox.org/permlink/csfB0mdeYRE8Os9L

我还可以通过稍微修改x3 calc8 / calc9示例来重现这一点:只需更改分配规则

auto const assignment_def =
        variable
    >   '='
    >   expression
    >   ';'
    ;

auto const assignment_def =
        expression
    >   '='
    >   expression
    >   ';'
    ;

并将assignment.lhs的类型更改为expression(并修复lhs的出现次数)

Boost版本:1.63 Comiler:gcc(Ubuntu)5.4

0 个答案:

没有答案