如何使用boost :: spirit将一个单词序列解析成一个向量?

问题描述:

我在努力学习boost::spirit。作为一个例子,我试图将一系列的单词解析成一个vector<string>。我尝试这样做:如何使用boost :: spirit将一个单词序列解析成一个向量?

#include <boost/spirit/include/qi.hpp> 
#include <boost/foreach.hpp> 

namespace qi = boost::spirit::qi; 

int main() { 

    std::vector<std::string> words; 
    std::string input = "this is a test"; 

    bool result = qi::phrase_parse(
     input.begin(), input.end(), 
     +(+qi::char_), 
     qi::space, 
     words); 

    BOOST_FOREACH(std::string str, words) { 
    std::cout << "'" << str << "'" << std::endl; 
    } 
} 

,给了我这样的输出:

'thisisatest' 

,但我想下面的输出,其中每个字分别匹配:

'this' 
'is' 
'a' 
'test' 

如果可能的话,我d喜欢避免为这个简单情况定义我自己的qi::grammar子类。

你从根本上误解的(或至少滥用)跳过解析器– qi::space,作为跳读分析器的目的,是使你的解析器不可知的空白,使得在a bab之间没有什么区别。

在你的情况下,空格重要的,因为你希望它分隔单词。因此,你不应该跳过空格,并要使用qi::parse,而不是qi::phrase_parse

#include <vector> 
#include <string> 
#include <iostream> 
#include <boost/foreach.hpp> 
#include <boost/spirit/include/qi.hpp> 

int main() 
{ 
    namespace qi = boost::spirit::qi; 

    std::string const input = "this is a test"; 

    std::vector<std::string> words; 
    bool const result = qi::parse(
     input.begin(), input.end(), 
     +qi::alnum % +qi::space, 
     words 
    ); 

    BOOST_FOREACH(std::string const& str, words) 
    { 
     std::cout << '\'' << str << "'\n"; 
    } 
} 

(现在用G. Civardi的修复更新。)

+0

很好解释,+1 – sehe

我相信这是最低版本。 qi :: omit应用于qi列表解析器分隔符是不必要的 - 它不会生成任何输出属性。详情请参阅:http://www.boost.org/doc/libs/1_48_0/libs/spirit/doc/html/spirit/qi/reference/operator/list.html

#include <string> 
#include <iostream> 
#include <boost/foreach.hpp> 
#include <boost/spirit/include/qi.hpp> 

int main() 
{ 
    namespace qi = boost::spirit::qi; 

    std::string const input = "this is a test"; 

    std::vector<std::string> words; 
    bool const result = qi::parse(
     input.begin(), input.end(), 
     +qi::alnum % +qi::space, 
     words 
); 

    BOOST_FOREACH(std::string const& str, words) 
    { 
     std::cout << '\'' << str << "'\n"; 
    } 
} 

以防万一别人遇到我的领先空间问题。

我一直在使用ildjarn的解决方案,直到遇到以某些空格开头的字符串。

std::string const input = " this is a test"; 

我花了一段时间才发现领先空间导致函数qi :: parse(...)失败。解决的办法是在调用qi :: parse()之前修剪输入的前导空格。