【问题标题】:How to use boost::spirit to parse a sequence of words into a vector?如何使用 boost::spirit 将单词序列解析为向量?
【发布时间】:2012-05-12 09:43:17
【问题描述】:

我正在努力学习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 子类。

【问题讨论】:

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


    【解决方案1】:

    您从根本上误解了(或至少滥用)跳过解析器的目的 - qi::space,用作跳过解析器,是为了使您的解析器空白不可知,因此 a b 和 @ 之间没有区别987654323@.

    在您的情况下,空格 很重要,因为您希望它来分隔单词。因此,您不应该跳过空格,并且您想使用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 的修复程序。)

    【讨论】:

      【解决方案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";
        }
      }
      

      【讨论】:

        【解决方案3】:

        以防其他人遇到我的前导空格问题。

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

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

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

        【讨论】:

        • 那是因为别人给你推荐的东西是错误的。您不应该将phrase_parse 更改为解析。正确的方法是使用 lexeme[].
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-08-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-26
        相关资源
        最近更新 更多