Parsen in mehrere Vektorelemente

Ich möchte eine Zeichenfolge rekursiv analysieren und die Ergebnisse in einer Struktur speichern. Ich habe einen Parser geschrieben, der eine Iteration verarbeiten kann. Die Eingabe ist wie folgt formatiert:

v  1.5 2.0 2.5
v  3.0 3.5 4.0
f 1 2 3
f 4 5 6 
v  4.5 5.0 5.5
v  6.0 6.5 7.0
f 7 8 9
f 10 11 12

Das Problem ist, dass nur die ersten 4 Zeilen analysiert werden und beim dritten gefundenen 'v' angehalten wird. Der vollständige Code ist unten angegeben. Wie ändere ich diesen Code, damit er auch den Rest der Eingabe in dieselbe Struktur analysiert? Ich habe versucht, die Startregel von zu ändernstart = vertex >> elements zustart = *(vertex >> elements), aber das gibt nur einen großen Kompilierungsfehler. Gleiches gilt fürstart = +(vertex >> elements). Irgendwelche Ideen, wie ich die Regeln ändern soll?

#include <iostream>
#include <sstream>
#include <fstream>

#include "boost/spirit/include/qi.hpp"
#include "boost/spirit/include/support_iso8859_1.hpp"
#include "boost/fusion/include/adapt_struct.hpp"


struct ElemParseData
{
    std::vector<float> verts;
    std::vector<unsigned int> idx;
};

BOOST_FUSION_ADAPT_STRUCT(
    ElemParseData,
    (std::vector<float>, verts)
    (std::vector<unsigned int>, idx)
)


bool doParse( ElemParseData &parseData, const std::string &data )
{
    namespace qi      = boost::spirit::qi;
    namespace iso8859 = boost::spirit::iso8859_1;

    struct objGram : qi::grammar<std::string::const_iterator, ElemParseData(), iso8859::space_type>
    {
        objGram() : objGram::base_type(start)
        {
            vertex   = *('v' >> qi::double_ >> qi::double_ >> qi::double_);
            elements = *('f' >> qi::int_ >> qi::int_ >> qi::int_);

            start = vertex >> elements;
        }

        qi::rule<std::string::const_iterator, ElemParseData(), iso8859::space_type> start;
        qi::rule<std::string::const_iterator, std::vector<float>(), iso8859::space_type> vertex;
        qi::rule<std::string::const_iterator, std::vector<unsigned int>(), iso8859::space_type> elements;

    } objGrammar;

    std::string::const_iterator f = data.cbegin();
    bool res = qi::phrase_parse( f, data.cend(), objGrammar, iso8859::space, parseData );


    // print everything that hasn't been processed by the parser
    std::cout << "#### Trail ####" << std::endl;
    std::cout << std::string(f, data.cend()) << std::endl;

    return res;
}


int main( int argc, char* argv[] )
{
    std::stringstream ss;
    std::filebuf fb;
    if ( fb.open("parsetest.txt", std::ios::in) )
    {
        std::istream is(&fb);
        while (is)
            ss << char(is.get());
        fb.close();
    }


    ElemParseData parseData;
    bool res = doParse( parseData, ss.str() );


    // print results
    std::cout << std::endl << "Parsing result: " << res << std::endl;
    std::cout << "---######### ResultData #########---" << std::endl;
    std::cout << "---- Begin vertex data ----" << std::endl;
    std::vector<float>::iterator it;
    for ( it = parseData.verts.begin(); it != parseData.verts.end(); ++it )
        std::cout << *it << std::endl;
    std::cout << "---- End vertex data ----" << std::endl;

    std::cout << std::endl;

    std::cout << "---- Begin index data ----" << std::endl;
    std::vector<unsigned int>::iterator idxIt;
    for ( idxIt = parseData.idx.begin(); idxIt != parseData.idx.end(); ++idxIt )
            std::cout << *idxIt << std::endl;
    std::cout << "---- End index data ----" << std::endl;

    std::cout << "Press enter to exit" << std::endl;
    std::cin.get();
}

P.S .: Bei Bedarf kann der Kompilierungsfehler gefunden werdenHier.

EDIT: Ich versuche, einen Wavefront .OBJ-Parser zu schreiben. Die Eingabe hier ist nur eine Vereinfachung meines Problems.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage