Spirit Qi und Strings



  • Hi,
    hat jemand eine Ahnung warum ich mit Qi nicht direkt in QStrings parsen kann?

    std::string t = "Hallo";
      std::string s;
      qi::rule<std::string::iterator> rule = +qi::char_[phoenix::ref(s) += qi::_1];
      qi::parse(t.begin(), t.end(), rule);
    
      QString t2 = "Hallo";
      QString s2;
      qi::rule<QString::iterator> rule2 = +qi::char_[phoenix::ref(s2) += qi::_1];
      qi::parse(t2.begin(), t2.end(), rule2);
    

    Der obere Teil funkioniert. Der untere nicht. Irgendwas mit QChar und int. 😕



  • Vielleicht, weil Qi Qchar nicht kennt (was nicht sehr überraschend ist)?



  • Was ich eigentlich möchte ist Folgendes:

    using namespace std;
       namespace qi = boost::spirit::qi;
       using boost::spirit::qi::double_;
       using boost::spirit::qi::_1;
       using boost::spirit::qi::phrase_parse;
       using boost::spirit::ascii::space;
       using boost::phoenix::ref;
    
       QString t;
       qi::rule<string::iterator, QString()> r1 = (+qi::char_)[hier fehlt was];
       qi::rule<string::iterator > r = r1[ref(t) = _1];
       string temp("Hallo");
       phrase_parse(temp.begin(), temp.end(), r, qi::space);
    

    Anschlißend sollte eigentlich 'Hallo' in 't' stehen. Wenn da nicht diese unverständlichen Compiler Erros wären. Ob das nun QString oder eine anderer Attribute Typ ist sollte egal sein. Ich vermute das da eine Funktion oder Funktor fehlt, die/der aufgerufen wird mit dem geparsten Inhalt von (+qi::char_) und dem Rückgabewert des Attribute - Typs.



  • vielleicht gehts mit einer der statischen QString::fromXYZ()'s?



  • Die Lösung ist

    namespace boost { namespace spirit { namespace traits
    {
      // Make Qi recognize QString as a container
      template <> struct is_container<QString> : mpl::true_ {};
    
      // Expose the container's (QString's) value_type
      template <> struct container_value<QString> : mpl::identity<QChar> {};
    
      // Define how to insert a new element at the end of the container (QString)
      template <>
      struct push_back_container<QString, QChar>
      {
        static bool call(QString& c, QChar const& val)
        {
          c.append(val);
          return true;
        }
      };
    }}}
    

    Damit macht man neue Container bei Spirit bekannt. 😉


Anmelden zum Antworten