boost spirit x3 元组构造和隐式 unused_type
boost spirit x3 tuple construction and implicit unused_type
阅读文档,我认为下面应该可以正常工作,但它无法编译,除非我不将输出传递给 phrase_parse
调用,在这种情况下它可以正常工作,但我可以'得不到我想要的数据。似乎 nvp_def 有 (string, unused_type, uin32_t)
的类型,(正如我阅读文档)会创建一个元组,正如我所期望的,但显然情况并非如此。我缺少什么才能获取解析数据?
#include <boost/spirit/home/x3.hpp>
#include <tuple>
namespace x3 = boost::spirit::x3;
x3::rule<class idtype, std::string> const idrule = "idrule";
auto const idrule_def = x3::lexeme[+x3::char_("a-zA-Z0-9")];
x3::rule<class nvp, std::tuple<std::string, uint32_t>> const nvp = "nvp";
auto const nvp_def = idrule >> x3::char_(':') >> x3::hex;
BOOST_SPIRIT_DEFINE(idrule, nvp);
int main(int argc, char *argv[])
{
std::tuple<std::string, uint32_t> output;
const std::string total = "foo4bar:deadbeef";
std::string::const_iterator first = total.begin();
std::string::const_iterator const last = total.end();
bool r = x3::phrase_parse(first, last, nvp, x3::space, output);
}
编译错误(试图将 uint32_t 从十六进制分配给元组):
/usr/include/boost/spirit/home/x3/support/traits/move_to.hpp:62: error: no match for ‘operator=’ (operand types are ‘std::tuple<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned int>’ and ‘std::remove_reference<unsigned int&>::type {aka unsigned int}’)
dest = std::move(src);
~~~~~^~~~~~~~~~~~~~~~
您的主要问题是缺少包含:<boost/fusion/include/std_tuple.hpp>
; without this adapter std::tuple
is not a valid Fusion sequence,因此 Spirit 无法使用它来存储复合属性。 (N.b。您的示例也缺少 <string>
和 <stdint.h>
。)
你的第二个问题是 x3::char_
有一个属性,但你不需要分隔冒号的属性,所以 nvp_def
应该是 idrule >> ':' >> x3::hex
或 idrule >> x3::lit(':') >> x3::hex
.另请注意,x3::hex
的实际属性是 unsigned
,因此使用 uint32_t
字段存储它可能会在某些平台上被截断。
阅读文档,我认为下面应该可以正常工作,但它无法编译,除非我不将输出传递给 phrase_parse
调用,在这种情况下它可以正常工作,但我可以'得不到我想要的数据。似乎 nvp_def 有 (string, unused_type, uin32_t)
的类型,(正如我阅读文档)会创建一个元组,正如我所期望的,但显然情况并非如此。我缺少什么才能获取解析数据?
#include <boost/spirit/home/x3.hpp>
#include <tuple>
namespace x3 = boost::spirit::x3;
x3::rule<class idtype, std::string> const idrule = "idrule";
auto const idrule_def = x3::lexeme[+x3::char_("a-zA-Z0-9")];
x3::rule<class nvp, std::tuple<std::string, uint32_t>> const nvp = "nvp";
auto const nvp_def = idrule >> x3::char_(':') >> x3::hex;
BOOST_SPIRIT_DEFINE(idrule, nvp);
int main(int argc, char *argv[])
{
std::tuple<std::string, uint32_t> output;
const std::string total = "foo4bar:deadbeef";
std::string::const_iterator first = total.begin();
std::string::const_iterator const last = total.end();
bool r = x3::phrase_parse(first, last, nvp, x3::space, output);
}
编译错误(试图将 uint32_t 从十六进制分配给元组):
/usr/include/boost/spirit/home/x3/support/traits/move_to.hpp:62: error: no match for ‘operator=’ (operand types are ‘std::tuple<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned int>’ and ‘std::remove_reference<unsigned int&>::type {aka unsigned int}’)
dest = std::move(src);
~~~~~^~~~~~~~~~~~~~~~
您的主要问题是缺少包含:<boost/fusion/include/std_tuple.hpp>
; without this adapter std::tuple
is not a valid Fusion sequence,因此 Spirit 无法使用它来存储复合属性。 (N.b。您的示例也缺少 <string>
和 <stdint.h>
。)
你的第二个问题是 x3::char_
有一个属性,但你不需要分隔冒号的属性,所以 nvp_def
应该是 idrule >> ':' >> x3::hex
或 idrule >> x3::lit(':') >> x3::hex
.另请注意,x3::hex
的实际属性是 unsigned
,因此使用 uint32_t
字段存储它可能会在某些平台上被截断。