2012-05-02 9 views
7

Estoy tratando de aprender boost::spirit. Como ejemplo, estoy tratando de analizar una secuencia de palabras en un vector<string>. He intentado esto:Cómo usar boost :: spirit para analizar una secuencia de palabras en un vector?

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

que me da este resultado:

'thisisatest' 

pero quería la siguiente salida, donde cada palabra es igualada por separado:

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

Si es posible, me Me gusta evitar tener que definir mi propia subclase qi::grammar para este caso simple.

Respuesta

13

Estás malentendido fundamentalmente el propósito de (o al menos mal uso) de un analizador de salto – qi::space, que se utiliza como un analizador de salto, sirve para hacer que su analizador de espacio en blanco agnóstico tal que no hay diferencia entre a b y ab.

En su caso, el espacio en blanco es importante, ya que quiere delimitar palabras. En consecuencia, usted no debe saltarse los espacios en blanco, y que desea utilizar en lugar de qi::parseqi::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"; 
    } 
} 

(ahora se actualiza con fix de G. Civardi.)

+0

bien explicado, +1 – sehe

2

Creo que esta es la versión mínima. qi :: omit aplicado en la lista qi separador de analizador no es necesario - no genera ningún atributo de salida. Para más detalles ver: 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"; 
    } 
} 
1

Sólo en caso de otra persona ejecute en mi problema de los espacios iniciales.

He estado usando la solución de ildjarn, hasta que encontré una cadena que comienza con algunos espacios.

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

Me tomó un tiempo para darse cuenta de que el espacio inicial conduce a un fallo del qi función :: parse (...). La solución es recortar los espacios iniciales de entrada antes de llamar a qi :: parse().

Cuestiones relacionadas