Simple Spirit X3 分词器无法编译,属性不匹配
Simple Spirit X3 word splitter won't compile, attribute mismatch
我正在尝试使用 Spirit X3 解析器来处理命令行工具的输出,但遇到了问题。我已将它们缩小到一个我不理解其行为的最小示例:
#include <string>
#include <vector>
#include <boost/spirit/home/x3.hpp>
int main() {
namespace x3 = boost::spirit::x3;
std::wstring const str = L"bonjour je suis un petit panda";
auto word = x3::lexeme[+x3::alpha];
std::wstring s;
x3::phrase_parse(begin(str), end(str), word, x3::space, s); // OK
std::vector<std::wstring> v;
x3::phrase_parse(begin(str), end(str), *word, x3::space, v); // Compiler error
}
错误很毛茸茸,但归结为无法调用 move_to
,IIUC 是属性类型不匹配的症状。
/usr/local/include/boost/spirit/home/x3/support/traits/move_to.hpp:180:9: error: no matching function for call to 'move_to'
detail::move_to(std::move(src), dest
^~~~~~~~~~~~~~~
[...]
/usr/local/include/boost/spirit/home/x3/support/traits/move_to.hpp:56:9: note: candidate function not viable: no known conversion from 'typename attribute_category<basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> > >::type' (aka 'boost::spirit::x3::traits::container_attribute') to 'boost::spirit::x3::traits::unused_attribute' for 3rd argument
move_to(Source&&, Dest&, unused_attribute) {}
^
/usr/local/include/boost/spirit/home/x3/support/traits/move_to.hpp:74:9: note: candidate function not viable: no known conversion from 'typename attribute_category<basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> > >::type' (aka 'boost::spirit::x3::traits::container_attribute') to 'boost::spirit::x3::traits::plain_attribute' for 3rd argument
move_to(Source&& src, Dest& dest, plain_attribute)
^
/usr/local/include/boost/spirit/home/x3/support/traits/move_to.hpp:97:9: note: candidate function not viable: no known conversion from 'typename attribute_category<basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> > >::type' (aka 'boost::spirit::x3::traits::container_attribute') to 'boost::spirit::x3::traits::tuple_attribute' for 3rd argument
move_to(Source&& src, Dest& dest, tuple_attribute)
^
/usr/local/include/boost/spirit/home/x3/support/traits/move_to.hpp:106:9: note: candidate function not viable: no known conversion from 'typename attribute_category<basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> > >::type' (aka 'boost::spirit::x3::traits::container_attribute') to 'boost::spirit::x3::traits::tuple_attribute' for 3rd argument
move_to(Source&& src, Dest& dest, tuple_attribute)
^
/usr/local/include/boost/spirit/home/x3/support/traits/move_to.hpp:150:9: note: candidate function not viable: no known conversion from 'typename attribute_category<basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> > >::type' (aka 'boost::spirit::x3::traits::container_attribute') to 'boost::spirit::x3::traits::variant_attribute' for 3rd argument
move_to(Source&& src, Dest& dest, variant_attribute tag)
^
/usr/local/include/boost/spirit/home/x3/support/traits/move_to.hpp:85:35: note: candidate template ignored: disabled by 'enable_if' [with Source = const wchar_t, Dest = std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >]
inline typename enable_if<is_container<Source>>::type
^
/usr/local/include/boost/spirit/home/x3/support/traits/move_to.hpp:113:9: note: candidate function template not viable: requires 4 arguments, but 3 were provided
move_to(Source&& src, Dest& dest, variant_attribute, mpl::false_)
^
/usr/local/include/boost/spirit/home/x3/support/traits/move_to.hpp:143:9: note: candidate function template not viable: requires 4 arguments, but 3 were provided
move_to(Source&& src, Dest& dest, variant_attribute, mpl::true_)
^
/usr/local/include/boost/spirit/home/x3/support/traits/move_to.hpp:157:9: note: candidate function template not viable: requires 4 arguments, but 3 were provided
move_to(Iterator, Iterator, unused_type, unused_attribute) {}
^
/usr/local/include/boost/spirit/home/x3/support/traits/move_to.hpp:161:9: note: candidate function template not viable: requires 4 arguments, but 3 were provided
move_to(Iterator first, Iterator last, Dest& dest, container_attribute)
^
/usr/local/include/boost/spirit/home/x3/support/traits/move_to.hpp:171:9: note: candidate function template not viable: requires 4 arguments, but 3 were provided
move_to(Iterator first, Iterator last, boost::iterator_range<Iterator>& rng, container_attribute)
^
我的目标是用空格对句子进行分词。 word
解析器 returns 将第一个完整单词按预期转换为 std::string
。为什么 *word
不直接兼容 std::vector<std::string>
,我应该写什么?
我不确定它是否真的适用于第一种情况。
您正在使用 ASCII 版本的字符解析器(x3::alpha
是 x3::standard::alpha
的同义词),传递的迭代器值类型是 wchar_t
,但是 boost::spirit::char_encoding::standard::ischar()
returns 非 ascii 字符为 false。
使用 x3::standard_wide::alpha
有效:
#include <string>
#include <vector>
#include <boost/spirit/home/x3.hpp>
int main() {
namespace x3 = boost::spirit::x3;
std::wstring const str = L"bonjour je suis un petit panda";
auto word = x3::lexeme[+x3::standard_wide::alpha];
std::wstring s;
x3::phrase_parse(begin(str), end(str), word, x3::space, s); // OK
std::vector<std::wstring> v;
x3::phrase_parse(begin(str), end(str), *word, x3::space, v); // OK
}
另一个好问题应该与 ASCII 船长一起使用,如果 x3::standard::space
和 x3::standard_wide::space
之间存在差异(由于 Unicode,宽字符可能会将更多字符视为空格)。
我正在尝试使用 Spirit X3 解析器来处理命令行工具的输出,但遇到了问题。我已将它们缩小到一个我不理解其行为的最小示例:
#include <string>
#include <vector>
#include <boost/spirit/home/x3.hpp>
int main() {
namespace x3 = boost::spirit::x3;
std::wstring const str = L"bonjour je suis un petit panda";
auto word = x3::lexeme[+x3::alpha];
std::wstring s;
x3::phrase_parse(begin(str), end(str), word, x3::space, s); // OK
std::vector<std::wstring> v;
x3::phrase_parse(begin(str), end(str), *word, x3::space, v); // Compiler error
}
错误很毛茸茸,但归结为无法调用 move_to
,IIUC 是属性类型不匹配的症状。
/usr/local/include/boost/spirit/home/x3/support/traits/move_to.hpp:180:9: error: no matching function for call to 'move_to'
detail::move_to(std::move(src), dest
^~~~~~~~~~~~~~~
[...]
/usr/local/include/boost/spirit/home/x3/support/traits/move_to.hpp:56:9: note: candidate function not viable: no known conversion from 'typename attribute_category<basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> > >::type' (aka 'boost::spirit::x3::traits::container_attribute') to 'boost::spirit::x3::traits::unused_attribute' for 3rd argument
move_to(Source&&, Dest&, unused_attribute) {}
^
/usr/local/include/boost/spirit/home/x3/support/traits/move_to.hpp:74:9: note: candidate function not viable: no known conversion from 'typename attribute_category<basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> > >::type' (aka 'boost::spirit::x3::traits::container_attribute') to 'boost::spirit::x3::traits::plain_attribute' for 3rd argument
move_to(Source&& src, Dest& dest, plain_attribute)
^
/usr/local/include/boost/spirit/home/x3/support/traits/move_to.hpp:97:9: note: candidate function not viable: no known conversion from 'typename attribute_category<basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> > >::type' (aka 'boost::spirit::x3::traits::container_attribute') to 'boost::spirit::x3::traits::tuple_attribute' for 3rd argument
move_to(Source&& src, Dest& dest, tuple_attribute)
^
/usr/local/include/boost/spirit/home/x3/support/traits/move_to.hpp:106:9: note: candidate function not viable: no known conversion from 'typename attribute_category<basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> > >::type' (aka 'boost::spirit::x3::traits::container_attribute') to 'boost::spirit::x3::traits::tuple_attribute' for 3rd argument
move_to(Source&& src, Dest& dest, tuple_attribute)
^
/usr/local/include/boost/spirit/home/x3/support/traits/move_to.hpp:150:9: note: candidate function not viable: no known conversion from 'typename attribute_category<basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> > >::type' (aka 'boost::spirit::x3::traits::container_attribute') to 'boost::spirit::x3::traits::variant_attribute' for 3rd argument
move_to(Source&& src, Dest& dest, variant_attribute tag)
^
/usr/local/include/boost/spirit/home/x3/support/traits/move_to.hpp:85:35: note: candidate template ignored: disabled by 'enable_if' [with Source = const wchar_t, Dest = std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >]
inline typename enable_if<is_container<Source>>::type
^
/usr/local/include/boost/spirit/home/x3/support/traits/move_to.hpp:113:9: note: candidate function template not viable: requires 4 arguments, but 3 were provided
move_to(Source&& src, Dest& dest, variant_attribute, mpl::false_)
^
/usr/local/include/boost/spirit/home/x3/support/traits/move_to.hpp:143:9: note: candidate function template not viable: requires 4 arguments, but 3 were provided
move_to(Source&& src, Dest& dest, variant_attribute, mpl::true_)
^
/usr/local/include/boost/spirit/home/x3/support/traits/move_to.hpp:157:9: note: candidate function template not viable: requires 4 arguments, but 3 were provided
move_to(Iterator, Iterator, unused_type, unused_attribute) {}
^
/usr/local/include/boost/spirit/home/x3/support/traits/move_to.hpp:161:9: note: candidate function template not viable: requires 4 arguments, but 3 were provided
move_to(Iterator first, Iterator last, Dest& dest, container_attribute)
^
/usr/local/include/boost/spirit/home/x3/support/traits/move_to.hpp:171:9: note: candidate function template not viable: requires 4 arguments, but 3 were provided
move_to(Iterator first, Iterator last, boost::iterator_range<Iterator>& rng, container_attribute)
^
我的目标是用空格对句子进行分词。 word
解析器 returns 将第一个完整单词按预期转换为 std::string
。为什么 *word
不直接兼容 std::vector<std::string>
,我应该写什么?
我不确定它是否真的适用于第一种情况。
您正在使用 ASCII 版本的字符解析器(x3::alpha
是 x3::standard::alpha
的同义词),传递的迭代器值类型是 wchar_t
,但是 boost::spirit::char_encoding::standard::ischar()
returns 非 ascii 字符为 false。
使用 x3::standard_wide::alpha
有效:
#include <string>
#include <vector>
#include <boost/spirit/home/x3.hpp>
int main() {
namespace x3 = boost::spirit::x3;
std::wstring const str = L"bonjour je suis un petit panda";
auto word = x3::lexeme[+x3::standard_wide::alpha];
std::wstring s;
x3::phrase_parse(begin(str), end(str), word, x3::space, s); // OK
std::vector<std::wstring> v;
x3::phrase_parse(begin(str), end(str), *word, x3::space, v); // OK
}
另一个好问题应该与 ASCII 船长一起使用,如果 x3::standard::space
和 x3::standard_wide::space
之间存在差异(由于 Unicode,宽字符可能会将更多字符视为空格)。