Boost :: Spirit解析规则中的复合属性生成

jay*_*947 2 boost boost-spirit boost-spirit-qi

我有以下解析规则:

filter = (input >> (qi::repeat(0,2)[char_(';') >> input]))
Run Code Online (Sandbox Code Playgroud)

input是一个规则,返回一个std::vector<int>我将vec简称为的向量.

问题是:filter规则返回什么复合属性?

我试过了:

fusion::vector <vec,std::vector <fusion::vector <char,vec> > >
Run Code Online (Sandbox Code Playgroud)

但它失败了,我不知道为什么.

seh*_*ehe 5

导致解析器表达式的属性类型相当良好记录.但这可能是迷失方向和耗费时间.

这是一个技巧:发送一个sentinel来检测属性类型:

struct Sniffer
{
    typedef void result_type;

    template <typename T>
    void operator()(T const&) const { std::cout << typeid(T).name() << "\n"; }
};
Run Code Online (Sandbox Code Playgroud)

然后使用folliing解析器表达式

 (input >> (qi::repeat(0,2)[qi::char_(';') >> input])) [ Sniffer() ]
Run Code Online (Sandbox Code Playgroud)

将转储:

N5boost6fusion7vector2ISt6vectorIsSaIsEES2_INS1_IcS4_EESaIS5_EEEE
Run Code Online (Sandbox Code Playgroud)

c++filt -1会告诉你代表:

boost::fusion::vector2<
    std::vector<short, std::allocator<short> >, 
    std::vector<boost::fusion::vector2<char, std::vector<short, std::allocator<short> > >, 
                std::allocator<boost::fusion::vector2<char, std::vector<short, std::allocator<short> > > 
            > > 
 >
Run Code Online (Sandbox Code Playgroud)

在Coliru上看到它:http://coliru.stacked-crooked.com/view?id = 3e767990571f8d0917aae745bccfa520-5c1d29aa57205c65cfb2587775d52d22

boost::fusion::vector2<std::vector<short, std::allocator<short> >, std::vector<std::vector<short, std::allocator<short> >, std::allocator<std::vector<short, std::allocator<short> > > > >
Run Code Online (Sandbox Code Playgroud)

它可能是如此令人惊讶地复杂,部分原因char_(";")可能是';'(或更明确地lit(';')).与此相比(Coliru):

boost::fusion::vector2<
    std::vector<short, ... >, 
    std::vector<std::vector<short, std::allocator<short> >, ... > >
Run Code Online (Sandbox Code Playgroud)

这应该回答你的问题.

旁注:解析事物

不要低估Spirit中的自动属性传播.通常,您不必为确切暴露的属性类型而烦恼.相反,依赖于Spirit使用的(很多)属性转换将它们分配给提供的属性引用.

我相信你知道list-operator(%)的精神?我会告诉你如何使用它而不用多说:

vector<vector<short>> data;

qi::parse(f, l, qi::short_ % ',' % ';', data);
Run Code Online (Sandbox Code Playgroud)

现在,如果您需要强制执行它可能是1-3个元素的事实,您可以使用epsPhoenix操作来断言最大大小:

const string x = "1,2,3;2,3,4;3,4,5";
auto f(begin(x)), l(end(x));

if (qi::parse(f, l, 
        (qi::eps(phx::size(qi::_val) < 2) > (qi::short_ % ',')) % ';'
        , data))
{
    cout << karma::format(karma::short_ % ',' % ';', data) << "\n";
}
cout << "remaining unparsed: '" << std::string(f,l) << "'\n";
Run Code Online (Sandbox Code Playgroud)

打印:

1,2,3;2,3,4
remaining unparsed: ';3,4,5'
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

218 次

最近记录:

12 年,1 月 前