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

标签 boost boost-spirit boost-spirit-qi

我有以下解析规则:

filter = (input >> (qi::repeat(0,2)[char_(';') >> input]))

input是返回 std::vector<int> 的规则,我将其称为 vec 的向量简而言之。

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

我尝试过:

fusion::vector <vec,std::vector <fusion::vector <char,vec> > >

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

最佳答案

解析器表达式产生的属性类型为 quite嗯-documented 。但这可能会让人迷失方向并且耗时。

这里有一个技巧:发送哨兵来检测属性类型:

struct Sniffer
{
    typedef void result_type;

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

然后使用下面的解析器表达式

 (input >> (qi::repeat(0,2)[qi::char_(';') >> input])) [ Sniffer() ]

将转储:

N5boost6fusion7vector2ISt6vectorIsSaIsEES2_INS1_IcS4_EESaIS5_EEEE

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

在 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> > > > >

它可能是如此令人惊讶的复杂,部分原因是 char_(";") 可能是 ';' (或者更明确地 lit(' ;'))。 Constrast with this (Coliru) :

boost::fusion::vector2<
    std::vector<short, ... >, 
    std::vector<std::vector<short, std::allocator<short> >, ... > >

这应该可以回答您的问题。

旁注:解析事物

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

我相信您知道列表运算符 (%) 的本质吗?我将向您展示如何使用它,无需多言:

vector<vector<short>> data;

qi::parse(f, l, qi::short_ % ',' % ';', data);

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

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

打印:

1,2,3;2,3,4
remaining unparsed: ';3,4,5'

关于boost - Boost::Spirit 解析规则中的复合属性生成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17870613/

相关文章:

c++ - boost chrono endTime - startTime 在 boost 1.51 中返回负值

C++:让 Boost 工作;关于包含路径和链接库的问题

c++ - Boost Spirit 信号成功解析,尽管 token 不完整

c++ - Boost Spirit Qi Symbols默认值和NULL值

c++ - 用 boost spirit 解析转义的字符串

c++ - 什么时候是浮点运算 'invalid' ?

c++ - 如何将 boost::any_cast 转换为 std::string

c++ - Boost Karma - 非消耗谓词

c++ - 如何在 Spirit X3 中正确指定锚定条件?

c++ - Boost Spirit模板特化失败