Spirit Parsen von Vecktoren



  • Hi,
    ich habe ein Problem beim Parsen in std::vector. Das Code Beispiel kompiliert nicht. Ersetze ich das pair<> durch ein einfaches 'int' funtioniert jedoch alles. Hat jemand eine Idee, was ich zusätzlich tun muss, damit auch dieser Code funktioniert?

     using namespace boost::spirit;
     using namespace boost;
     using namespace std;
     qi::rule<std::string::iterator, vector<pair<string, int>>()> r1;
     qi::rule<std::string::iterator, pair<string, int>()> r2;
     qi::rule<std::string::iterator, vector<pair<string, int>>()> r3;
     r2 = +qi::alnum >> '=' >> qi::int_ >> ';';
     r3 = '{' >> *r2 >> '}';
     r1 = *r3; //fails
     string s = { "{a=1;}e=5;" };
     vector<pair<string, int>> v;
     phrase_parse(s.begin(), s.end(), r1, boost::spirit::ascii::space, v);
    


  • @sroeber sagte in Spirit Parsen von Vecktoren:

    kompiliert nicht

    Sehr präzise Fehlerbeschreibung ...



  • @manni66 Die Zeile r1 = *r3 kompiliert nicht. Ich dachte der genaue Fehler spielt keine große Rolle. Sind endlose Zeile im Spirit template Code.
    1>D:\Projekte\Devel11\Base\Libraries_VS2015_Win64\boost\boost/spirit/home/qi/detail/assign_to.hpp(152): error C2440: 'static_cast': cannot convert from 'const std::vector<std::pairstd::string,int,std::allocator<_Ty>>' to 'std::pairstd::string,int'
    1> with
    1> [
    1> _Ty=std::pairstd::string,int
    1> ]
    ...



  • Hallo,

    ich kenne mich mit boost::spirit nicht wirklich aus, aber mit r1 = *r3 sagst Du doch, dass Du eine Liste von "r3" haben willst. Und r3 ist selbst schon eine Liste. Also sollte der Typ von r1 doch eher so aussehen: qi::rule<std::string::iterator, vector<vector<pair<string, int>>>()>.



  • @djohn Ja, im Prinzip schon, allerdings ist r1 normalerweise noch mit r2 verodert. Dann ist das Problem das gleiche nur eben noch komplizierter. QI kann im Prinzip beliebig über Templates konfiguriert werden, wenn man weiß wie.



  • Möchtest du also

    r1 = r3 | *r2;
    

    d.h. sollen die geschweiften Klammern (von r3) optional sein?
    Dies könnte man aber auch direkt mit r3 lösen.



  • @th69 In dem Beispiel könnte man das vielleicht machen, in meiner echten Grammatik nicht.
    Ich suche nach einer Lösung um die Vektoren (durch das 😉 in einen Vektor zu transformieren. Mit einem vector<int> klappt das ja auch automatisch, nur eben nicht mit komplexen Typen wie z.B. pair<>. Zwei Vektoren können ja auch per vector::insert aneinander gehängt werden.



  • Du musst dafür semantic actions verwenden (und phoenix)

    // #include <boost/phoenix/stl/container.hpp>
    // namespace phoenix = boost::phoenix;
    
    // so ähnlich
    r1 = *r3 [phoenix::insert(_val, phoenix::begin(_1), phoenix::end(_1))]
    

    Ich kann das gerade nicht ausprobieren und ich bin rostig mit boost::qi, aber das sollte dich in die richtige richtung bringen.



  • @5cript Ok. Danke ich probier's. Ich hatte gehofft möglichst wenig Semantic Ations verwenden zu müssen, zumal es mit Vectoren von int auch ohne klappt.


Anmelden zum Antworten