Parser une chaine de caractere

Signaler
Messages postés
1
Date d'inscription
jeudi 1 janvier 2009
Statut
Membre
Dernière intervention
17 janvier 2010
-
Messages postés
1
Date d'inscription
mercredi 6 février 2008
Statut
Membre
Dernière intervention
9 juin 2010
-
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

Messages postés
1
Date d'inscription
mercredi 6 février 2008
Statut
Membre
Dernière intervention
9 juin 2010

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