2012-05-02 30 views
7

Sto cercando di imparare boost::spirit. Ad esempio, sto cercando di analizzare una sequenza di parole in un vector<string>. Ho provato questo:Come usare boost :: spirit per analizzare una sequenza di parole in un vettore?

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

che mi dà questo output:

'thisisatest' 

ma ho voluto il seguente output, dove ogni parola è abbinato separatamente:

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

Se possibile, I' Mi piacerebbe evitare di dover definire la mia sottoclasse qi::grammar per questo semplice caso.

risposta

13

Stai fondamentalmente fraintendendo lo scopo di (o almeno un uso improprio) un salto parser – qi::space, utilizzato come un parser di salto, è per fare il parser spazi bianchi agnostico tale che non v'è alcuna differenza tra a b e ab.

Nel tuo caso, lo spazio vuoto è importante, come vuoi che delimiti le parole. Di conseguenza, non si dovrebbe essere saltando gli spazi bianchi, e si desidera utilizzare qi::parse piuttosto che 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"; 
    } 
} 

(ora aggiornato con la correzione di G. Civardi.)

+0

ben spiegato, +1 – sehe

2

Credo che questa è la versione minima. qi :: omit applicato sul separatore di parser di qi list non è necessario - non genera alcun attributo di output. Per maggiori dettagli si veda: 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

Solo nel caso qualcun altro correre nel mio problema di spazi iniziali.

mi ha utilizzato la soluzione di Ildjarn, fino a quando mi sono imbattuto in una stringa che inizia con alcuni spazi.

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

ci ho messo un po 'per capire che lo spazio iniziale porta a un fallimento della funzione di qi :: parse (...). La soluzione è di tagliare gli spazi iniziali dell'input prima di chiamare qi :: parse().

Problemi correlati