Parser une chaine de caractere

amira2010 Messages postés 1 Date d'inscription jeudi 1 janvier 2009 Statut Membre Dernière intervention 17 janvier 2010 - 17 janv. 2010 à 22:06
ammo35 Messages postés 1 Date d'inscription mercredi 6 février 2008 Statut Membre Dernière intervention 9 juin 2010 - 9 juin 2010 à 23:05
J'ai utilisé boost::spirit pour lire une chaine de caractère a partir d'un fichier , mon probleme c'est que l'analyseur skip les espaces voici le code :
#include "planParser.h"

PlanParser::PlanParser()
{
    //ctor
}

PlanParser::~PlanParser()
{
    //dtor
}

bool PlanParser::parse(std::istream& ist)
{
    base_iterator_type deb(ist);
    return parse(deb,base_iterator_type());
}

bool PlanParser::parse(base_iterator_type first, base_iterator_type last)
{
   // using boost::spirit::space_p;
    bool r = boost::spirit::qi::/*phrase_*/parse(
        first,
        last,
        getParser(),
       // ,boost::spirit::qi::char_('!')//eoi//space
       // boost::spirit::space
    );
    if (first != last)
        return false;
    return r;
}

boost::spirit::qi::rule PlanParser::getParser()
{
    return *((+(boost::spirit::qi::char_ - boost::spirit::qi::char_(':')))[newPlage]//[boost::bind(&PlanParser::newPlage, this, _1)]
        >> boost::spirit::qi::char_(':')
        >> (boost::spirit::qi::int_ >> boost::spirit::qi::char_('/') >> boost::spirit::qi::int_ >> boost::spirit::qi::char_('/') >> boost::spirit::qi::int_ )[startDate]//[boost::bind(&PlanParser::newPlage, this, _1)]
        >> boost::spirit::qi::char_('-')>> boost::spirit::qi::char_('>')
        >> (boost::spirit::qi::int_ >> boost::spirit::qi::char_('/') >> boost::spirit::qi::int_ >> boost::spirit::qi::char_('/') >> boost::spirit::qi::int_ )[endDate]//[boost::bind(&PlanParser::newPlage, this, _1)]
        >> boost::spirit::qi::char_(':')
        >> (+(boost::spirit::qi::char_- boost::spirit::qi::char_('.')))[name]
        >>boost::spirit::qi::char_('.')
        )

    ;
}

boost::gregorian::date fusion5toDate(boost::fusion::vector5 date)
{
    int year = boost::fusion::at_c<4>(date);
    //std::cout << year << std::endl;
    if (year >= 0 && year < 80) year += 2000;
    else if (year >= 80 && year < 100) year += 1900;
    //std::cout << year << std::endl;
    assert(year > 1900 && year < 2100);

    return boost::gregorian::date(year,boost::fusion::at_c<2>(date),boost::fusion::at_c<0>(date));
}

void /*PlanParser::*/newPlage(const std::vector<char>& str)
{
    std::cout << "a new plage for : " << std::string(str.begin(),str.end()) << std::endl;
}
void /*PlanParser::*/startDate(boost::fusion::vector5 date)
{
    std::cout << "starting : " << fusion5toDate(date) << std::endl;
}
void /*PlanParser::*/endDate(boost::fusion::vector5 date)
{
    std::cout << "ending : " << fusion5toDate(date) << std::endl;
}
void /*PlanParser::*/name(const std::vector<char>& str)
{
    std::cout << "named : " << std::string(str.begin(),str.end()) << std::endl;
}
void /*PlanParser::*/finalizePlage()
{
    std::cout << "done" << std::endl;
}


j'attend votre aide
merci

1 réponse

ammo35 Messages postés 1 Date d'inscription mercredi 6 février 2008 Statut Membre Dernière intervention 9 juin 2010
9 juin 2010 à 23:05
Salut,

Le message étant vieux, je suppose que tu as trouvé la solution mais au cas où, tu utilises boost::spirit::space au lieu de boost::spirit::qi::space.
bool r = boost::spirit::qi::parse(
first,
last,
getParser(),
boost::spirit::qi::space
);

Je pense que c'est le problème même si je suis plus que débutant en spirit. D'ailleurs, je trouve ton code beaucoup plus propre que tous les exemples que j'ai pu trouvé sur spirit::qi car il est encapsuler dans un objet plutôt que dans un namespace. Comme je veux pouvoir lancer plusieurs parseurs en même temps et en parallèle, cela me convient aussi mieux. Pourrais tu me dire ce qui se passe exactement en terme d'instanciation de template dans la fonction GetParser, que je sois certain que cela pourra être multithread.
Aurais tu d'autres exemples dans le même sens avec des sous règles plutôt que tout dans une seule ligne.
D'avance merci.
Oli
0
Rejoignez-nous