我基于精灵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