IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Boost C++ Discussion :

boost spirit (pb avec les espaces)


Sujet :

Boost C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Futur Membre du Club
    Inscrit en
    Janvier 2010
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 4
    Par défaut boost spirit (pb avec les espaces)
    Bonjour,
    J'ai utilisé boost spirit pour lire et afficher une liste de chaines de caractères, mon problème c'est que le parseur ne prend pas en compte les espaces. voici un bout de code qui explique qu'est ce que j'ai fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
     
    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<base_iterator_type> 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_('.')
            )
     
        ;
    }
    J'attend votre aide
    Merci

  2. #2
    Futur Membre du Club
    Inscrit en
    Janvier 2010
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 4
    Par défaut
    Bonjour à nouveau,

    Je me rend compte que je n'ai pas donné beaucoup de précisions dans mon premier message. Voici une explication plus avancée.

    Je suis entrain d’essayer de parser une liste de chaines de caractères à l’aide de boost ::spirit.

    Voici un exemple de la liste de chaine de caractères que je veux parser :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Georges Orwell : 01/01/09 -> 01/01/50 : disponible un jour sur deux.
    Steve O Connor : 01/08/09 -> 01/01/50 : disponible.
    Mon but c’est d’obtenir en sortie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    a new plage for : Georges Orwell
    starting : 2009-Jan-01
    ending : 2050-Jan-01
    named : disponible un jour sur deux
    Alors que j’obtiens comme sortie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    a new plage for : GeorgesOrwell
    starting : 2009-Jan-01
    ending : 2050-Jan-01
    named : disponibleunjoursurdeux
    Mon problème c’est que le parseur skip les espaces, du coup j’obtiens 'GeorgesOrwell' au lieu de ‘Georges Orwell’.

    Attention cependant, je veux skipper les espaces dans le reste de la phrase. Par exemple :
    est exactement équivalent à :
    ou à
    J’ai essayé de mettre l’expression qui parse la chaine de caractère ‘Georges Orwell’ dans un lexeme pour inhiber le saut d’espace mais ca ne résout pas le problème.

    Voici la définition de mon parser :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    boost::spirit::qi::rule<base_iterator_type> PlanParser::getParser()
    {
        using boost::spirit::qi;
        return *(lexeme[*(char_- char_(':'))][newPlage]
            >> char_(':')
            >> (int_ >> char_('/') >> int_ >> char_('/') >> int_ )[startDate]
            >> char_('-')>> char_('>')
            >> (int_ >> char_('/') >> int_ >> char_('/') >> int_ )[endDate]
            >> char_(':')
            >> (+(char_- char_('.')))[name]
            >>char_('.')
            )
        ;
    }
    et voici comment je l'utilise :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    bool PlanParser::parse(base_iterator_type first, base_iterator_type last)
    {
        bool r = boost::spirit::qi::parse(
            first,
            last,
            getParser()       
        );
        if (first != last)
            return false;
        return r;
    }
    Peut-être n'ai-je pas compris l'utilisation de lexeme, ou bien peut-être n'est-ce pas la bonne méthode ?

    Merci à ceux qui auront eu la patience de lire et à ceux qui m'aideront

  3. #3
    Membre expérimenté
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2004
    Messages
    230
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2004
    Messages : 230
    Par défaut
    Ton parseur bien que peu clair je trouve a l'air correcte
    Tu as deux methodes pour les espaces, soit tu les parses a la main, en gros tu cree une regle pour les parser (pas tres dure), soit tu dis a ton parseur de les consumer avec la regle predefinis: boost::spirit::ascii::space_type.

    Sinon si je n'ai pas repondu a ta question, je n'ai pas compris ton erreur.

    Cependant je me permet de te conseiller de separer tes regles. Genre tu fais une regle file, qui utilise une regle genre parseBidule, un bidule qui se decompose en un machinchose et un truc ...

    Je te mets un exemple d'un parseur JSon pour que tu vois ce que je voulais dire par decomposition:
    (c'est du spirit V2)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
     
    template<typename Iterator>
    struct JSonGrammar : boost::spirit::qi::grammar<Iterator, JSonPair(), boost::spirit::ascii::space_type>
    {
    	JSonGrammar() :
    	    JSonGrammar::base_type(json)
    	{
     
    	    using boost::spirit::qi::lit;
    	    using boost::spirit::qi::lexeme;
    	    using boost::spirit::ascii::char_;
    	    using boost::spirit::ascii::string;
    	    using namespace boost::spirit::qi::labels;
     
    	    using boost::phoenix::at_c;
    	    using boost::phoenix::push_back;
     
    	    string_	=	lexeme[
    					   '"' >>
    					   *(
    						   (char_('\\')[_val += _1] >> char_[_val += _1]) |
    						   (char_[_val += _1]- '"')
    					   )
    					   >> '"'
     
    	           	  	       ];
     
    	    json 	= 	dict[_val = _1] | pair[_val = _1] | array[at_c<1>(_val) = _1];
     
    	    dict 	= 	'{' >>	pair[_val += _1] % ',' >> '}';
     
    	    array	=	'[' >> value[_val += _1] % ',' >> ']';
     
    	    pair	=    	string_ [at_c<0>(_val) = _1] >> ':' >> value [at_c<1>(_val) = _1];
     
    	    value	=	lit("null") [_val = reinterpret_cast<void*>(NULL)]
    					| lit("true") [_val = true]
    					| lit("false") [_val = false]
    					| string_ [_val = _1]
    					| qi::double_ [_val = _1]
    					| array[_val += _1]
    					| dict[_val += _1]
    					;
     
    	}
     
    	boost::spirit::qi::rule<Iterator, std::string(), boost::spirit::ascii::space_type> string_;
    	boost::spirit::qi::rule<Iterator, JSonPair(), boost::spirit::ascii::space_type> json;
    	boost::spirit::qi::rule<Iterator, JSonPair(), boost::spirit::ascii::space_type> dict;
    	boost::spirit::qi::rule<Iterator, JSonPair(), boost::spirit::ascii::space_type> pair;
    	boost::spirit::qi::rule<Iterator, JSonValue(), boost::spirit::ascii::space_type> value;
    	boost::spirit::qi::rule<Iterator, JSonValue(), boost::spirit::ascii::space_type> array;
    };
    Dans ce code je dis a toutes mes regles d'ignorer les espaces. J'annule cependant la regle avec lexeme dans la regle string_

  4. #4
    Futur Membre du Club
    Inscrit en
    Janvier 2010
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 4
    Par défaut
    Bonsoir,

    Tout d’abord merci beaucoup pour vos conseils que j’ai appréciés.

    Peut être je n’ai pas bien expliqué, mais mon problème se résume sur le fait qu’au niveau du parsing dans des parties j’ai voulu ignorer les espaces
    01 /01/09->01/01/5
    est equivalent à

    01 /01/0 9 -> 01/01/50
    par contre, dans d’autres parties j’ai besoin de garder les espaces. par exemple pour les chaines :
    Georges Orwell
    et

    disponible un jour sur deux

    Pour plus d’informations, j’ai définit un seul parseur et qui m’a donnée comme résultat l’ignorance de tous les espaces (par contre je cherche une solution pour garder les espaces dans des parties).

    J’espère que ce sera plus clair.

    Merci

  5. #5
    Membre expérimenté
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2004
    Messages
    230
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2004
    Messages : 230
    Par défaut
    Soit tu mets des marqueurs genre "machin chose" et tu fais un lexeme dessus pour le parser et je pense qeu c la meilleur methode.

    Sinon tu peux aussi parser en lexeme jusqu'au ':' ....


    enfin a toi de voir

  6. #6
    Futur Membre du Club
    Inscrit en
    Janvier 2010
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 4
    Par défaut
    Salut,
    Merci encore pour votre aide.

    J’ai essayé de mettre l’expression qui parse la chaine de caractère ‘Georges Orwell’ dans un lexeme pour inhiber le saut d’espace mais ca ne résout pas le problème.
    Pour ce faire, voila qu’est ce que j’ai fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    lexeme[*(char_- char_(':'))]
    Est-ce que j’ai pas bien utilisé le lexème ?

Discussions similaires

  1. [MySQL] Requête MySQL : problèmes avec les espaces
    Par superseba888 dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 06/07/2007, 16h12
  2. [RegEx] Problème avec les espaces entre deux tags
    Par elcoyotos dans le forum Langage
    Réponses: 9
    Dernier message: 17/04/2007, 11h01
  3. Problème avec les espaces dans un tableau !
    Par remixtech dans le forum Balisage (X)HTML et validation W3C
    Réponses: 1
    Dernier message: 10/07/2006, 19h30
  4. [VBS]Problème de chemin avec les " " (espace)
    Par pierre1256 dans le forum VBScript
    Réponses: 3
    Dernier message: 16/02/2006, 18h53
  5. [Winsock] Problème avec les espaces
    Par Fiquet dans le forum Développement
    Réponses: 3
    Dernier message: 12/01/2006, 18h06

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo