使用boost Spirit解析为STL向量

时间:2018-04-29 09:47:26

标签: c++ parsing boost stdvector boost-spirit

我正在学习Boost Spirit 2,我无法弄清楚为什么我无法将两个整数的序列解析为int的STL向量。来自&gt;&gt;的文档operator {here)我知道语法rounded = tf.round(Y) C = 0 V = 0 sumseen = 0. sumtrue = 0. avgg = 0. def avgfunc(elm): global C global V global sumseen global sumtrue global avgg tru = Y_[C] ***tf.add(V,1)*** cond1 = tf.count_nonzero(tf.cast(tf.equal(elm,tf.constant(1.,tf.float32)),tf.float32)) cond2 = tf.count_nonzero(tf.cast(tf.equal(elm,tru[V]),tf.float32)) if(cond1 == 1): sumseen+=1 if(cond2 == 1): sumtrue+=1 ***if(V >= 79): V = 0 avgg = ((sumtrue/sumseen)*100) if sumseen !=0 else 0*** return sumseen def _comparefunc(elem_probs): global C tru = Y_[C] mapout = tf.map_fn(avgfunc, elem_probs) ***C = C+1 if(C == 49): C = 0*** return avgg outputafter = tf.map_fn(_comparefunc, rounded) accuracyofbatch = tf.reduce_mean(outputafter) 的属性应该是int_ >> int_。从attribute notation documentation我知道“vector<int>的符号代表任何STL容器持有A类元素。”

然而,当我尝试向vector<A>添加一个以int_ >> int_为属性的动作时,编译失败。

在其他错误消息中,它说:std::vector

我知道this question(“让boost :: spirit :: qi使用stl容器”),但那里的解决方案 - 包括std_tuple.hpp - 没有改变任何东西。

为什么会这样?

/usr/include/boost/bind/mem_fn_template.hpp:163:7: note:   no known conversion for argument 2 from ‘boost::fusion::vector<int, int>’ to ‘const std::vector<int>&’

1 个答案:

答案 0 :(得分:3)

int_ >> int_合成一个int元组,int.¹

如果您想强制合成容器,请将其repeat(2) [ int_ ]表示。

  

Sidenote :正如您将在下面看到的那样,即使绑定属性是cotainer,也存在属性兼容性的空间,因此您不需要。

  带有解析器表达式的

Sidenote auto询问未定义的行为:Assigning parsers to auto variables

  

Sidenote :您的输入使用空格分隔符,但解析器不使用空格分隔符。那永远不会奏效。

您的代码示例似乎与目标没什么关系,所以这是我的小例子:

1。 vector<int>

<强> Live On Coliru

#include <boost/spirit/include/qi.hpp>
using Vec = std::vector<int>;
namespace qi = boost::spirit::qi;

template <typename It> Vec parse_ivec(It first, It last) {
    Vec v;
    if (qi::phrase_parse(first, last,  qi::int_ >> qi::int_ >> qi::eoi, qi::space, v))
        return v;
    throw std::runtime_error("Parse failed");
}

Vec parse_ivec(std::string const& r) { return parse_ivec(begin(r), end(r)); }

int main() {
    for (int i : parse_ivec("12 13")) {
        std::cout << i << "\n";
    }
}

打印

12
13

2。改编结构

或者,如果你想要一个结构,而不是std::vector<>

<强> Live On Coliru

#include <boost/fusion/adapted/struct.hpp>
struct Vec { int a, b; };
BOOST_FUSION_ADAPT_STRUCT(Vec, a, b)

#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;

template <typename It> Vec parse_ivec(It first, It last) {
    Vec v;
    if (qi::phrase_parse(first, last,  qi::int_ >> qi::int_ >> qi::eoi, qi::space, v))
        return v;
    throw std::runtime_error("Parse failed");
}

Vec parse_ivec(std::string const& r) { return parse_ivec(begin(r), end(r)); }

int main() {
    Vec vec = parse_ivec("12 13");
    std::cout << vec.a << " " << vec.b << "\n";
}

打印

12 13

3。 std::tuple<int, int>

<强> Live On Coliru

#include <boost/fusion/adapted/std_tuple.hpp>
using Vec = std::tuple<int, int>;

#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;

template <typename It> Vec parse_ivec(It first, It last) {
    Vec v;
    if (qi::phrase_parse(first, last,  qi::int_ >> qi::int_ >> qi::eoi, qi::space, v))
        return v;
    throw std::runtime_error("Parse failed");
}

Vec parse_ivec(std::string const& r) { return parse_ivec(begin(r), end(r)); }

int main() {
    Vec vec = parse_ivec("12 13");
    std::cout << std::get<0>(vec) << " " << std::get<1>(vec) << "\n";
}

打印

12 13

¹从技术上讲,这是一个Fusion序列,它可以与std :: pair等类型的东西兼容,或者你自己的类型适应。