2016-05-24 12 views
3

Wie Boost.Spirit x3 können in structs analysieren mag:Parsing in structs mit Containern

struct person{ 
    std::string name; 
    std::vector<std::string> friends; 
} 

von Boost.Spirit v2 Kommen würde ich eine Grammatik verwenden, aber da Unterstützung Grammatiken doesnt X3 habe ich keine Ahnung, wie um das sauber zu machen.

EDIT: Es wäre schön, wenn jemand mir eine Liste von Strings und gibt einen Parser Schreiben helfen könnte, ein person mit dem ersten String-Parsing ist der Name und die res der Saiten sind im friends Vektor.

Antwort

8

Parsing mit x3 ist viel einfacher als mit v2, so dass Sie nicht zu viel Mühe haben sollten. Grammatiken weg zu sein ist eine gute Sache!

Hier ist, wie Sie in einen Vektor von Strings analysieren kann:

//#define BOOST_SPIRIT_X3_DEBUG 

#include <fstream> 
#include <iostream> 
#include <string> 
#include <type_traits> 
#include <vector> 

#include <boost/fusion/include/adapt_struct.hpp> 
#include <boost/fusion/include/io.hpp> 
#include <boost/spirit/home/x3.hpp> 
#include <boost/spirit/home/x3/support/ast/variant.hpp> 

namespace x3 = boost::spirit::x3; 

struct person 
{ 
    std::string name; 
    std::vector<std::string> friends; 
}; 

BOOST_FUSION_ADAPT_STRUCT(
    person, 
    (std::string, name) 
    (std::vector<std::string>, friends) 
); 

auto const name = x3::rule<struct name_class, std::string> { "name" } 
       = x3::raw[x3::lexeme[x3::alpha >> *x3::alnum]]; 

auto const root = x3::rule<struct person_class, person> { "person" } 
       = name >> *name; 

int main(int, char**) 
{ 
    std::string const input = "bob john ellie"; 
    auto it = input.begin(); 
    auto end = input.end(); 

    person p; 
    if (phrase_parse(it, end, root >> x3::eoi, x3::space, p)) 
    { 
     std::cout << "parse succeeded" << std::endl; 
     std::cout << p.name << " has " << p.friends.size() << " friends." << std::endl; 
    } 
    else 
    { 
     std::cout << "parse failed" << std::endl; 
     if (it != end) 
      std::cout << "remaining: " << std::string(it, end) << std::endl; 
    } 

    return 0; 
} 

Wie Sie on Coliru sehen können, ist der Ausgang:

Parse gelang bob 2 Freunde.

+0

Für was ist x3 :: position_tagged? – Exagon

+0

@Exagon Ich bin mir nicht sicher, sie benutzen es in so ziemlich allen Samples, die ich gefunden habe, also habe ich mich daran gewöhnt, es hinzuzufügen. Es ist eine Weile her, seit ich etwas x3 gemacht habe. – Borgleader

+3

Selbst macht es nichts. Sie müssten zusätzliche Operationen in der Regel-Tag-Struktur haben, um eine "aspektorientierte Attributanreicherung" zu haben. So wie es ist, sollten Sie die Basisklasse – sehe