Meine Absicht ist es, eine kommagetrennte Liste von Werten in einen verschachtelten Vektor zu analysieren. Diese Liste ist zweidimensional. Die grundlegende Frage ist:In einen Vektor <Vektor <double>> mit boost :: spirit zerlegen
ist es möglich, in einen Vektor des Vektors mit boost :: spirit zu analysieren?
So etwas wie die Tabelle unter „Traction“:
'
' RPM
0,5000,10000,15000,20000,25000
'
' Temp
'
-40.,0.,20.,40.
'
' Traction
200.,175.,170.,165.,160.,150.
200.,175.,170.,165.,160.,150.
165.,165.,160.,155.,145.,145.
160.,155.,150.,145.,145.,140.
'
In einem weiteren Schritt würde Ich mag in 4-dimensionalen Daten lesen, aber jetzt mit der zweiten Dimension Ich bin zu kämpfen. Die Datenstruktur ist wie folgt:
struct table {
std::vector<double> index;
std::vector<double> index2;
std::vector<std::vector<double> > base;
};
Die Grammatik ist IMHO ziemlich einfach wie folgt:
comment %= qi::lexeme[ '\'' >> *(qi::standard::char_ - qi::eol)] >> qi::eol;
commentblock = comment >> *(comment);
doublevector = qi::double_ % ',' >> qi::eol ;
vectorblock = *doublevector;
start = commentblock >>
doublevector >>
commentblock >>
doublevector >>
commentblock >>
vectorblock >>
commentblock >>
qi::eoi
;
Bisher habe ich kein Problem Parsen der beiden Vektoren index
und index2
. Aber das Problem beginnt bei base
. Ich denke, dass der entscheidende Abschnitt ist, wo ich die vectorblock
definieren:
vectorblock = *doublevector;
ich mehrere Varianten dieser Aussage versucht haben. Auch der %=
Operator von this Frage hat nichts geändert. Obwohl die Attributausbreitung die richtige Richtung sein könnte.
Wenn ich die Boost-Dokumentation Beispiel "with style" folgen, ist das Ergebnis genau das gleiche:
vectorblock = doublevector % qi::eps;
Die Liste Redux Proben, die push_back()
verwenden:
vectorblock = doublevector[phoenix::push_back(qi::_val, qi::_1)] % qi::eps;
provozieren eine Flut von Fehlern kompilieren , beginnend mit:
Fehler C2039: 'push_back': ist kein Mitglied von 'boost :: spirit :: unused_type'
Update: Das Problem bei der Erklärung der vectorblock
war. Ich habe die ()
nach dem Attributtyp vergessen. So sollte die Definition wie folgt aussehen:
qi::rule<Iterator, std::vector<std::vector<double> >(), Skipper> vectorblock;
Die (aktualisiert) Arbeitsbeispiel ist hier:
#include <iostream>
#include <string>
#include <vector>
#define BOOST_SPIRIT_DEBUG
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/fusion/adapted.hpp>
struct table {
std::vector<double> index;
std::vector<double> index2;
std::vector<std::vector<double> > base;
};
BOOST_FUSION_ADAPT_STRUCT(
table,
(std::vector<double> , index)
(std::vector<double> , index2)
(std::vector<std::vector<double> >, base)
)
const std::string contents =
"'\n"
"' RPM\n"
"'\n"
"0,5010,10000,15000,20000,25000\n"
"'\n"
"' Temp\n"
"'\n"
"-40.,0.,20.,40.\n"
"'\n"
"' Traction\n"
"200.,175.,170.,165.,160.,150.\n"
"200.,175.,170.,165.,160.,150.\n"
"165.,165.,160.,155.,145.,145.\n"
"160.,155.,150.,145.,145.,140.\n"
"'\n"
;
int main()
{
namespace qi = boost::spirit::qi;
namespace phoenix = boost::phoenix;
typedef std::string::const_iterator Iterator;
typedef boost::spirit::ascii::blank_type Skipper;
qi::rule<Iterator, std::string(), Skipper> comment;
qi::rule<Iterator, Skipper> commentblock;
qi::rule<Iterator, std::vector<double>(), Skipper> doublevector;
qi::rule<Iterator, std::vector<std::vector<double> >, Skipper> vectorblock;
qi::rule<Iterator, table(), Skipper> start;
comment %= qi::lexeme[ '\'' >> *(qi::standard::char_ - qi::eol)] >> qi::eol;
commentblock = comment >> *(comment);
doublevector = qi::double_ % ',' >> qi::eol ;
vectorblock = *doublevector;
start = commentblock >>
doublevector >>
commentblock >>
doublevector >>
commentblock >>
vectorblock >>
commentblock >>
qi::eoi
;
BOOST_SPIRIT_DEBUG_NODES((start)(doublevector)(vectorblock));
table tref;
bool rv = qi::phrase_parse(
std::begin(contents), std::end(contents),
start,
boost::spirit::ascii::blank,
tref
);
std::cout << "parse " << ((char *)rv?"success":"failure") << ".\n";
for (auto i : tref.index)
std::cout << i << ", ";
std::cout << "\n";
for (auto i : tref.index2)
std::cout << i << ", ";
std::cout << "\nBase:\n";
for (auto & i : tref.base)
{
for(auto & j : i)
std::cout << j << ", ";
std::cout << "\n";
}
std::cout << std::endl;
}
Sie haben vergessen, die '()' in dem Attributtyp der Regel Deklaration für "Vektorblock". Nachdem ich es dort hingelegt habe, hat es für mich mit '* doublevector' funktioniert. – Wintermute
Sie sind richtig. wie dumm von mir! – user23573