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

时间:2012-05-02 21:15:09

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

我正在努力学习boost::spirit。作为一个例子,我试图将一系列单词解析为vector<string>。我试过这个:

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

如果可能的话,我想避免为这个简单的案例定义我自己的qi::grammar子类。

3 个答案:

答案 0 :(得分:13)

您从根本上误解了(或至少滥用)跳过解析器的目的 - qi::space,用作跳过解析器,用于使您的解析器空白不可知,以便{之间没有区别{1}}和a b

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

qi::phrase_parse

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

答案 1 :(得分:2)

我相信这是最小版本。 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";
  }
}

答案 2 :(得分:1)

以防其他人遇到我的领先空间问题。

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

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

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