2012-05-02 4 views
7

Ich versuche zu lernen boost::spirit. Als Beispiel versuche ich eine Folge von Wörtern in eine vector<string> zu parsen. Ich versuchte dies:Wie boost :: spirit verwenden, um eine Folge von Wörtern in einen Vektor zu analysieren?

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

das gibt mir diese Ausgabe:

'thisisatest' 

aber ich wollte die folgende Ausgabe, wobei jedes Wort einzeln abgestimmt ist:

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

Wenn möglich, ich Ich möchte vermeiden, dass ich für diesen einfachen Fall meine eigene Unterklasse qi::grammar definieren muss.

Antwort

13

Sie Missverständnis grundsätzlich den Zweck (oder zumindest missbräuchlich) Auslassungs Parser – qi::space, als Skip-Parser verwendet wird, ist Ihr Parser Leerzeichen Agnostiker für die Herstellung, so dass es keinen Unterschied zwischen a b und ab.

In Ihrem Fall ist der Whitespace wichtig, wie Sie wollen Wörter zu begrenzen. Daher sollten Sie nicht Leerzeichen werden übersprungen, und Sie wollen qi::parse verwenden, anstatt 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"; 
    } 
} 

(Jetzt mit G. Civardi der Fix aktualisiert.)

+0

gut erklärt, +1 – sehe

2

Ich glaube, das die Minimalversion ist. qi :: omit, das auf das Qi-Listen-Parser-Trennzeichen angewendet wird, ist nicht notwendig - es erzeugt keine Ausgabe-Attribute. Details siehe: 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

Für den Fall, jemand anderes in meinem Problem von führenden Leerzeichen führen.

Ich habe ildjarns Lösung verwendet, bis ich in eine Zeichenfolge kam, die mit einigen Leerzeichen beginnt.

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

Es hat eine Weile gedauert, bis ich herausgefunden habe, dass der führende Platz zu einem Ausfall der Funktion qi :: parse (...) führt. Die Lösung besteht darin, die führenden Leerzeichen vor dem Aufruf von qi :: parse() zu beschneiden.

Verwandte Themen