使用 boost::spirit 解析双打列表

发布于 2025-01-08 08:30:46 字数 1244 浏览 0 评论 0原文

这是一个代码示例。

// file temp.cpp

#include <iostream>

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

namespace qi = boost::spirit::qi;

struct parser : qi::grammar<std::string::const_iterator, std::vector<double> >
{
    parser() : parser::base_type( vector )
    {
        vector  = +qi::double_;
    }

    qi::rule<std::string::const_iterator, std::vector<double> > vector;
};

int main()
{
    std::string const x( "1 2 3 4" );
    std::string::const_iterator b = x.begin();
    std::string::const_iterator e = x.end();
    parser p;
    bool const r = qi::phrase_parse( b, e, p, qi::space );
    // bool const r = qi::phrase_parse( b, e, +qi::double_, qi::space ); // this this it PASSES
    std::cerr << ( (b == e && r) ? "PASSED" : "FAILED" ) << std::endl;
}

我想用 parser p 解析 std::string x

struct parser的定义来看,行

qi::phrase_parse( b, e, p, qi::space ); // PASSES

qi::phrase_parse( b, e, +qi::double_, qi::space ); // FAILS

应该是等效的。但是,第一个解析失败,第二个解析通过。

我在 struct parser 的定义中做错了什么?

Here is a code sample.

// file temp.cpp

#include <iostream>

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

namespace qi = boost::spirit::qi;

struct parser : qi::grammar<std::string::const_iterator, std::vector<double> >
{
    parser() : parser::base_type( vector )
    {
        vector  = +qi::double_;
    }

    qi::rule<std::string::const_iterator, std::vector<double> > vector;
};

int main()
{
    std::string const x( "1 2 3 4" );
    std::string::const_iterator b = x.begin();
    std::string::const_iterator e = x.end();
    parser p;
    bool const r = qi::phrase_parse( b, e, p, qi::space );
    // bool const r = qi::phrase_parse( b, e, +qi::double_, qi::space ); // this this it PASSES
    std::cerr << ( (b == e && r) ? "PASSED" : "FAILED" ) << std::endl;
}

I want to parse std::string x with parser p.

As follows from the definition of struct parser, the lines

qi::phrase_parse( b, e, p, qi::space ); // PASSES

and

qi::phrase_parse( b, e, +qi::double_, qi::space ); // FAILS

should be equivalent. However, the with first one parsing fails and with the second one it passes.

What am I doing wrong at the definition of struct parser ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

花海 2025-01-15 08:30:46

您应该“告知”有关跳过空格的语法 - 模板中的另一个参数。

#include <iostream> 

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

namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;

struct parser
  : qi::grammar<std::string::const_iterator, std::vector<double>(), ascii::space_type> 
{ 
  parser() : parser::base_type( vector ) 
  { 
    vector  %= +(qi::double_); 
  } 

  qi::rule<std::string::const_iterator, std::vector<double>(), ascii::space_type> vector;
}; 

int main() 
{ 
  std::string const x( "1 2 3 4" ); 
  std::string::const_iterator b = x.begin(); 
  std::string::const_iterator e = x.end(); 
  parser p; 
  bool const r = qi::phrase_parse( b, e, p, ascii::space ); 
  //bool const r = qi::phrase_parse( b, e, +qi::double_, qi::space );
  std::cout << ( (b == e && r) ? "PASSED" : "FAILED" ) << std::endl; 
} 

我还做了一些小修正,例如您应该在参数中添加括号,它告诉属性类型:std::vector()

You should "inform" grammar about skipping spaces - one more argument in template.

#include <iostream> 

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

namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;

struct parser
  : qi::grammar<std::string::const_iterator, std::vector<double>(), ascii::space_type> 
{ 
  parser() : parser::base_type( vector ) 
  { 
    vector  %= +(qi::double_); 
  } 

  qi::rule<std::string::const_iterator, std::vector<double>(), ascii::space_type> vector;
}; 

int main() 
{ 
  std::string const x( "1 2 3 4" ); 
  std::string::const_iterator b = x.begin(); 
  std::string::const_iterator e = x.end(); 
  parser p; 
  bool const r = qi::phrase_parse( b, e, p, ascii::space ); 
  //bool const r = qi::phrase_parse( b, e, +qi::double_, qi::space );
  std::cout << ( (b == e && r) ? "PASSED" : "FAILED" ) << std::endl; 
} 

I've also done few small corrections e.g. you should add brackets in arguments, which tells about attribute type: std::vector<double>().

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文