Boost spirit x3 示例计算器(calc8、calc9)链接器错误
Boost spirit x3 example calculator (calc8, calc9) linker error
我对提升精神(和提升)非常陌生。它非常有趣的图书馆。
我使用 qtcreator + MinGW 5.3。
我只是将 git_hub_calc8 中的每个源文件添加到新项目中并添加了一些 boost 库,但是我在尝试构建时遇到了以下错误(所有其他示例都可以正常工作)
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::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> > > > >, 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> >, std::__cxx11::list<client::ast::statement, std::allocator<client::ast::statement> > >(boost::spirit::x3::rule<client::parser::statement_class, std::__cxx11::list<client::ast::statement, std::allocator<client::ast::statement> >, 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> > > > >, 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&, std::__cxx11::list<client::ast::statement, std::allocator<client::ast::statement> >&)'
我做错了什么?我应该如何使用此示例创建项目?
似乎是 BOOST_SPIRIT_DECLARE 的问题,因为错误指出的地方是调用与此定义相关联的模板函数
(template <typename Iterator, typename Context, typename Attribute_>
bool parse(Iterator& first, Iterator const& last
, Context const& context, unused_type, Attribute_& attr) const
{
return parse_rule(*this, first, last, context, attr);
}
BOOST_SPIRIT_INSTANTIATE
marco 相当于做
namespace client { namespace parser
{
template bool parse_rule<iterator_type, context_type, statement_type::attribute_type>(
statement_type rule_, iterator_type &first, iterator_type const &last,
context_type const &context,
statement_type ::attribute_type &attr);
;
}}
所以关键是 iterator_type
和 context_type
匹配 完全 调用站点所需的那些。现在,未解析的符号是(demangled):
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::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> > > > >,
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> >,
std::__cxx11::list<client::ast::statement, std::allocator<client::ast::statement> >
>
(boost::spirit::x3::rule<client::parser::statement_class, std::__cxx11::list<client::ast::statement, std::allocator<client::ast::statement> >, 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> > > > >,
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 &,
std::__cxx11::list<client::ast::statement, std::allocator<client::ast::statement> >&)
这意味着 iterator_type 应该是:
__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >,
这确实是 std::string::const_iterator
在我的系统上的扩展。因此,上下文类型可能不匹配。通过在 BOOST_SPIRIT_INSTANTIATE
调用上方添加强制类型错误,如下所示:
struct {} _ = *static_cast<client::parser::context_type*>(nullptr);
我能够强制编译器在实例化时输出 context_type
的扩展类型:
statement.cpp:12 error: conversion from ‘client::parser::context_type {aka boost::spirit::x3::context<boost::spirit::x3::error_handler_tag, const std::reference_wrapper<boost::spirit::x3::error_handler<__gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> > > >, boost::spirit::x3::context<boost::spirit::x3::skipper_tag, const boost::spirit::x3::char_class<boost::spirit::char_encoding::ascii, boost::spirit::x3::space_tag>, boost::spirit::x3::unused_type> >}’ to non-scalar type ‘client::parser::<anonymous struct>’ requested
这告诉我们上下文类型是(为了易读而格式化):
boost::spirit::x3::context<
boost::spirit::x3::error_handler_tag,
const std::reference_wrapper<boost::spirit::x3::error_handler<
__gnu_cxx::__normal_iterator<const char *, std::__cxx11::basic_string<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> >,
但是:链接器将其设置为
boost::spirit::x3::context<
boost::spirit::x3::error_handler_tag,
std::reference_wrapper<boost::spirit::x3::error_handler<
__gnu_cxx::__normal_iterator<const char *, 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> >
最显着的区别在于 std::basic_string
(char_traits
和 allocator
)上默认模板参数的拼写,但这实际上并没有区别。不过,真正重要的区别在于缺少 const
和 reference_wrapper<>
类型。
修复它
我想这可能是 X3 历史上的一次改变。在这种情况下,最简单的解决方法是在 config.hpp:
中删除 const
typedef x3::context<
error_handler_tag
, std::reference_wrapper<error_handler_type>
, phrase_context_type>
context_type;
事实上,它现在可以编译
我对提升精神(和提升)非常陌生。它非常有趣的图书馆。
我使用 qtcreator + MinGW 5.3。 我只是将 git_hub_calc8 中的每个源文件添加到新项目中并添加了一些 boost 库,但是我在尝试构建时遇到了以下错误(所有其他示例都可以正常工作)
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::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> > > > >, 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> >, std::__cxx11::list<client::ast::statement, std::allocator<client::ast::statement> > >(boost::spirit::x3::rule<client::parser::statement_class, std::__cxx11::list<client::ast::statement, std::allocator<client::ast::statement> >, 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> > > > >, 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&, std::__cxx11::list<client::ast::statement, std::allocator<client::ast::statement> >&)'
我做错了什么?我应该如何使用此示例创建项目?
似乎是 BOOST_SPIRIT_DECLARE 的问题,因为错误指出的地方是调用与此定义相关联的模板函数
(template <typename Iterator, typename Context, typename Attribute_>
bool parse(Iterator& first, Iterator const& last
, Context const& context, unused_type, Attribute_& attr) const
{
return parse_rule(*this, first, last, context, attr);
}
BOOST_SPIRIT_INSTANTIATE
marco 相当于做
namespace client { namespace parser
{
template bool parse_rule<iterator_type, context_type, statement_type::attribute_type>(
statement_type rule_, iterator_type &first, iterator_type const &last,
context_type const &context,
statement_type ::attribute_type &attr);
;
}}
所以关键是 iterator_type
和 context_type
匹配 完全 调用站点所需的那些。现在,未解析的符号是(demangled):
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::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> > > > >,
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> >,
std::__cxx11::list<client::ast::statement, std::allocator<client::ast::statement> >
>
(boost::spirit::x3::rule<client::parser::statement_class, std::__cxx11::list<client::ast::statement, std::allocator<client::ast::statement> >, 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> > > > >,
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 &,
std::__cxx11::list<client::ast::statement, std::allocator<client::ast::statement> >&)
这意味着 iterator_type 应该是:
__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >,
这确实是 std::string::const_iterator
在我的系统上的扩展。因此,上下文类型可能不匹配。通过在 BOOST_SPIRIT_INSTANTIATE
调用上方添加强制类型错误,如下所示:
struct {} _ = *static_cast<client::parser::context_type*>(nullptr);
我能够强制编译器在实例化时输出 context_type
的扩展类型:
statement.cpp:12 error: conversion from ‘client::parser::context_type {aka boost::spirit::x3::context<boost::spirit::x3::error_handler_tag, const std::reference_wrapper<boost::spirit::x3::error_handler<__gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> > > >, boost::spirit::x3::context<boost::spirit::x3::skipper_tag, const boost::spirit::x3::char_class<boost::spirit::char_encoding::ascii, boost::spirit::x3::space_tag>, boost::spirit::x3::unused_type> >}’ to non-scalar type ‘client::parser::<anonymous struct>’ requested
这告诉我们上下文类型是(为了易读而格式化):
boost::spirit::x3::context<
boost::spirit::x3::error_handler_tag,
const std::reference_wrapper<boost::spirit::x3::error_handler<
__gnu_cxx::__normal_iterator<const char *, std::__cxx11::basic_string<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> >,
但是:链接器将其设置为
boost::spirit::x3::context<
boost::spirit::x3::error_handler_tag,
std::reference_wrapper<boost::spirit::x3::error_handler<
__gnu_cxx::__normal_iterator<const char *, 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> >
最显着的区别在于 std::basic_string
(char_traits
和 allocator
)上默认模板参数的拼写,但这实际上并没有区别。不过,真正重要的区别在于缺少 const
和 reference_wrapper<>
类型。
修复它
我想这可能是 X3 历史上的一次改变。在这种情况下,最简单的解决方法是在 config.hpp:
中删除const
typedef x3::context<
error_handler_tag
, std::reference_wrapper<error_handler_type>
, phrase_context_type>
context_type;
事实上,它现在可以编译