Boost.SSpirit.x3避免将同一类型的两个连续属性塌陷为向量
Boost.Spirit.x3 avoid collapsing two consecutive attributes of the same type into a vector
我正在努力学习BoostSpirit,但我发现了一个困难。
我正试图将一个字符串解析为以下结构:
struct employee {
std::string name;
std::string location;
};
看起来,当两个具有相同类型的属性背靠背时,它们(逻辑上)会塌陷为该类型的std::vector
。由于该规则,以下语法分析器
+x3::ascii::alnum >>
+x3::space >>
+x3::ascii::alnum
将具有CCD_ 2的属性。
但我正试图将其解析为struct
,这意味着对我来说理想的属性是boost::fusion::tuple<std::string, std::string>
,所以我可以将我的结构调整为它。
不工作代码的完整版本(如上所述):
// Example program
#include <iostream>
#include <string>
#include <boost/spirit/home/x3.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
struct employee {
std::string name;
std::string location;
};
BOOST_FUSION_ADAPT_STRUCT(employee,
(std::string, name),
(std::string, location)
)
namespace x3 = boost::spirit::x3;
x3::rule<struct parse_emp_id, employee> const parse_emp = "Employee Parser";
auto parse_emp_def =
+x3::ascii::alnum >>
+x3::space >>
+x3::ascii::alnum
;
BOOST_SPIRIT_DEFINE(parse_emp);
int main()
{
std::string input = "Joe Fairbanks";
employee ret;
x3::parse(input.begin(), input.end(), parse_emp, ret);
std::cout << "Name: " << ret.name << "tLocation: " << ret.location << std::endl;
}
实时查看
此代码触发static_assert
,告诉我我的属性不正确:
error: static_assert failed "Attribute does not have the expected size."
在的命令下
clang++ -std=c++14 test.cpp
(根据GCC,它也失败了)。
我尝试过的
我已经找到了解决这个问题的方法,但它很混乱,我不敢相信这是最干净的方法:
// Example program
#include <iostream>
#include <string>
#include <boost/spirit/home/x3.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
struct employee {
std::string name;
std::string location;
};
namespace x3 = boost::spirit::x3;
x3::rule<struct parse_emp_id, employee> const parse_emp = "Employee Parser";
auto parse_emp_def =
x3::eps [
([](auto& ctx) {
x3::_val(ctx) = employee{};
})
]>>
(+x3::ascii::alnum)[
([](auto& ctx) {
x3::_val(ctx).name = x3::_attr(ctx);
})
]>>
+x3::space >>
(+x3::ascii::alnum)[
([](auto& ctx) {
x3::_val(ctx).location = x3::_attr(ctx);
})
]
;
BOOST_SPIRIT_DEFINE(parse_emp);
int main()
{
std::string input = "Joe Fairbanks";
employee ret;
x3::parse(input.begin(), input.end(), parse_emp, ret);
std::cout << "Name: " << ret.name << "tLocation: " << ret.location << std::endl;
}
实时查看
我真的不喜欢这个解决方案:它有点破坏了精神的惊人表现力,让它变得超级丑陋,而且如果我想在employee
结构中添加新字段,那么我必须添加一个额外的lambda,而不仅仅是更新我的BOOST_FUSION_ADAPT_STRUCT
,这要容易得多。
所以问题是:有没有办法(希望)将相同类型的两个连续属性从std::vector
中干净地拆分为boost::fusion::vector
?
提前感谢您走到这一步;)。
问题在于,与字符文字不同,x3::space
有一个属性。因此,您没有两个由空格分隔的独立字符序列的属性,而是一个包含空格的大字符序列的一个属性。
omit
指令就是你想要的,通过这一次添加,你的"无效代码"就可以工作了。:-]
// Example program
#include <string>
#include <iostream>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/home/x3.hpp>
namespace x3 = boost::spirit::x3;
struct employee {
std::string name;
std::string location;
};
BOOST_FUSION_ADAPT_STRUCT(employee, name, location)
x3::rule<struct parse_emp_id, employee> const parse_emp = "Employee Parser";
auto parse_emp_def
= +x3::ascii::alnum
>> x3::omit[+x3::space]
>> +x3::ascii::alnum
;
BOOST_SPIRIT_DEFINE(parse_emp)
int main()
{
std::string const input = "Joe Fairbanks";
employee ret;
x3::parse(input.begin(), input.end(), parse_emp, ret);
std::cout << "Name: " << ret.name << "tLocation: " << ret.location << 'n';
}
在线演示
相关文章:
- 两个连续的 OpenMP 并行区域会相互减慢速度
- 可以将两个相同类型的连续数组视为一个数组吗?
- 我已经建立了递归关系,它找到了两个字符串之间最长的连续公共字符串,我怎么能跳过其中一个字符串中的一个字符
- 比较两个std::矢量/阵列,或者通常比较两个stl连续器
- 使用 C++ 读取具有两个连续分隔符的 csv 文件
- 为什么动态分配的两个变量的内存位置不是连续的?
- 子数组中两个数字的相同出现(连续)
- 如何比较C 列表中的两个连续元素
- 为什么两个执行矩阵乘法的过程并行运行比连续运行慢
- 如何生成没有两个相邻连续数字的排列
- 两个最大的连续子阵列
- 是否有任何方法可以比较C 中的STD ::的两个连续元素
- 为什么我不能在同一分配中保留两个连续的内存区域,而不通过单个调用保留这两个区域?
- 如何比较两个连续的迭代步骤?在C++
- 为什么两个连续的转换会改变一个整数
- 对于同一循环的这两个连续组,是否有更有效的解决方案
- Boost.SSpirit.x3避免将同一类型的两个连续属性塌陷为向量
- 如何检测两个连续的视频帧是否相同
- 在整数数据类型和连续两个字符类型之后.第 2 个字符的数据类型跳过..为什么
- 连续两个"cin"不起作用