Boost Spirit x3:解析向量,但仅有条件地将项目放入结果

问题描述 投票:0回答:1

考虑

(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]

这似乎也是错误的。

我该如何正确做?

c++ boost-spirit boost-spirit-x3
1个回答
0
投票

您的

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));

住在Coliru

#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]
© www.soinside.com 2019 - 2024. All rights reserved.