c++ - 使用 Boost.spirit 解析一个简单的重复文本宏

标签 c++ parsing boost-spirit-qi

我正在学习如何使用 Boost.Spirit 库来解析字符串。这似乎是一个非常好的工具,但也很困难。所以,我想解析一个用 / 分隔的单词的字符串并将它们放入字符串 vector 中。这是一个例子:word1/word2/word3 .这是一项简单的任务,我可以使用以下函数来完成:

bool r = phrase_parse(first, last, (+~char_("/") % qi::lit("/")),space,v)

哪里vstd::vector<std::string> .但总的来说,我想解析类似 w1/[w2/w3]2/w4 的内容相当于w1/w2/w3/w2/w3/w4 , 即 [w2/w3]2意味着 w2/w3重复两次。谁能给我一些想法吗?我读了documentation但仍然存在一些问题。

提前致谢!

最佳答案

完整的演示: live on Coliru

如果状态为 in_group,则 raw 值可选择以 ] 结束。

我选择使用继承属性(bool)传递状态。

此实现也允许嵌套子组,例如:"[w1/[w2/w3]2/w4]3"

#define BOOST_SPIRIT_DEBUG
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>

namespace phx = boost::phoenix;

int main()
{
    typedef std::string::const_iterator It;
    const std::string input = "[w1/[w2/w3]2/w4]3";

    std::vector<std::string> v;
    It first(input.begin()), last(input.end());

    using namespace boost::spirit::qi;

    rule<It, std::string(bool in_group)> raw;
    rule<It, std::vector<std::string>(bool in_group), space_type> 
        group, 
        delimited;

    _r1_type in_group; // friendly alias for the inherited attribute

    raw       = eps(in_group) >> +~char_("/]") 
              | +~char_("/");

    delimited = (group(in_group)|raw(in_group)) % '/';

    group     = ('[' >> delimited(in_group=true) >> ']' >> int_) 
        [ phx::while_(_2--) 
            [ phx::insert(_val, phx::end(_val), phx::begin(_1), phx::end(_1)) ]
        ];

    BOOST_SPIRIT_DEBUG_NODES((raw)(delimited)(group));

    bool r = phrase_parse(first, last, 
            delimited(false),
            space,v);

    if (r)
        std::copy(v.begin(), v.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
}

打印:

w1
w2
w3
w2
w3
w4
w1
w2
w3
w2
w3
w4
w1
w2
w3
w2
w3
w4

(除了调试信息)

关于c++ - 使用 Boost.spirit 解析一个简单的重复文本宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18377380/

相关文章:

c++ - 在 Boost Spirit Qi 中,我如何将每个字符匹配到下一个空格(带预跳过)

c++ - boost spirit 气 - 高效报价语法

c++ - Boost::spirit::qi 定义一个 nullaries 的计算器

c++ - cin和getline在一个程序里,只有一个生效?

regex - 使用 bash 脚本从 header 中提取父 url

ruby - 是否有用于解析营业时间的 RubyGem?

c++ - 如何将复杂的 json 转换为我可以在 C++ 中使用的东西

c++ - 当存在其他构造函数时,如何强制创建默认序列构造函数?

c++ - 如何每 200 秒使 io_service 发布特定功能?

c# - 仿函数在 C# 中有等效项吗?