Разбор списка пар с бустом :: spirit - PullRequest
2 голосов
/ 24 февраля 2012

Вот пример кода.

// 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;
}

Я хочу проанализировать std::string x с parser p.

Как следует из определения struct parser, строки

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

и

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

должны быть эквивалентны.Тем не менее, при первом разборе происходит сбой, а во втором он проходит.

Что я делаю неправильно при определении struct parser?

1 Ответ

2 голосов
/ 24 февраля 2012

Вы должны "сообщить" грамматике о пропусках пробелов - еще один аргумент в шаблоне.

#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<double>().

...