考虑
(int ":" int )*
形式的字符串。我想按以下方式将这样的字符串解析为整数向量:如果第二个值是奇数,则将第一个值添加到结果中。否则,请不要对这一对执行任何操作。
我正在尝试
auto pair_ = x3::rule<class pair_, int>()
= x3::int_ >> ":" >> x3::int_;
auto vec = x3::rule<class vec, std::vector<int>>()
= (*pair_[
([](auto &c){
if(x3::_attr(c).second % 2)
x3::_val(c).push_back(x3::_attr(c).first);
})
]);
这似乎是错误的。
附加任务:使
: int
可选,默认为 1。我尝试过
auto pair_ = x3::rule<class pair_, int>()
= x3::int_ >> ((":" >> x3::int_) | x3::attr(1));
示例:
10 11:0 12:3
应成为向量 [10, 12]
。
这似乎也是错误的。
我该如何正确做?
您的
pair_
规则仅公开一个 int 。改变
auto pair_
= x3::rule<class pair_, std::pair<int, int> >()
= x3::int_ >> ":" >> x3::int_;
会起作用,尽管你必须包括
#include <boost/fusion/adapted/std_pair.hpp>
直接或间接。可选版本也可以正常工作:
auto pair_
= x3::rule<class pair_, std::pair<int, int> >()
= x3::int_ >> (":" >> x3::int_ | x3::attr(1));
#include <boost/fusion/adapted/std_pair.hpp>
#include <boost/spirit/home/x3.hpp>
#include <fmt/ranges.h>
namespace x3 = boost::spirit::x3;
namespace Parsing {
auto pair_
= x3::rule<class pair_, std::pair<int, int> >()
= x3::int_ >> (":" >> x3::int_ | x3::attr(1));
auto action = [](auto& ctx) {
if (_attr(ctx).second % 2)
_val(ctx).push_back(_attr(ctx).first);
};
auto vec
= x3::rule<class vec, std::vector<int>>()
= *pair_[action];
}
int main() {
for (std::string_view input : {
"",
"12:4 1:1",
"12:4 1:1 2:2 3:3 4:4 5:5",
"12:4 1 2 3 4 5:5",
}) {
std::vector<int> v;
if (bool ok = phrase_parse(begin(input), end(input), Parsing::vec, x3::space, v))
fmt::print("{}\t'{}' -> {}\n", ok, input, v);
}
}
印刷
true '' -> []
true '12:4 1:1' -> [1]
true '12:4 1:1 2:2 3:3 4:4 5:5' -> [1, 3, 5]
true '12:4 1 2 3 4 5:5' -> [1, 2, 3, 4, 5]