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 : Encapsuler le parseur et ses résultats.


Sujet :

Boost C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre chevronné
    Inscrit en
    Août 2004
    Messages
    556
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 556
    Par défaut Boost::Spirit : Encapsuler le parseur et ses résultats.
    Plop !

    Je cherche désespérément le moyen d'encapsuler mes parsers.
    Je m'explique : je souhaiterais que les callback de mes parseurs soient des méthodes d'une certaine classe (appartenant au parser ou pas) et non des fonctions globales.

    Est-ce possible ?

    Pour l'instant j'utilises ce style: source mais ça ne me convient pas du tout dans l'optique de parser des échanges TCP, et la misère que ça peut faire si c'est en plus multi-thread :\

    Chacune de mes tentatives de syntaxe échouent lamentablement avec 14 pages d'erreur

  2. #2
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Peux-tu montrer un exemple de ce que tu tente de faire et qui échoue ?

    Par ailleurs, je ne vois pas le lien entre fonctions libres et problèmes de multi-thread.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  3. #3
    Membre chevronné
    Inscrit en
    Août 2004
    Messages
    556
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 556
    Par défaut
    Ouaip bien sûr

    Voici ce que je tente de faire:

    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
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
     
    struct IRCParser : public grammar<IRCParser>
    {
     
        template<typename ScannerT>
        struct definition
        {
     
            definition( IRCParser const& self)
            {
                message
                    =   ch_p(':')
                        >> nick
                        >> host
                        >> space_p
                        >> type
                        >> space_p
                        >> !argument
                        >> ch_p(':')
                        >> info
                    ;
                nick
                    =
                        (+alnum_p)[&this->nick_f] <==== Erreur
                        >> ch_p('!')
                    ;
                host
                    =
                        (
                            +alnum_p
                            >> ch_p('@')
                            >> +alnum_p
                            >> ch_p('.')
                            >> +alnum_p
                        )[&this->host_f]                  <==== Erreur
                    ;
                type
                    =
                        (+upper_p)[&this->type_f] <==== Erreur
                    ;
                argument
                    =
                        (+(anychar_p - ':'))[&this->arg_f] <==== Erreur
                    ;
                info
                    =   (*anychar_p)[&this->info_f] <==== Erreur
                    ;
            }
     
            rule<ScannerT> message, nick, host, type, argument, info;
     
            rule<ScannerT> const& start() const
            {
                return message;
            }
     
            string snick;
            string shost;
            string stype;
            string sarg;
            string sinfo;
     
            void nick_f( char const * first, char const * last ) { snick = string(first, last); }
            void host_f( char const * first, char const * last ) { shost = string(first, last); }
            void type_f( char const * first, char const * last ) { stype = string(first, last); }
            void arg_f ( char const * first, char const * last ) { sarg  = string(first, last); }
            void info_f( char const * first, char const * last ) { sinfo = string(first, last); }
     
        };
     
    };
     
    int main()
    {
        IRCParser r;
     
        string str = ":Nick!Host@name.here JOIN :#channel";
        parse( str.c_str(), r );
     
     
        return 0;
    }
    En gros, je souhaiterais après chaque parse réussi pouvoir récupérer les infos directement dans les membres du parser.

    Et le soucis du multi-thread c'est que admettons que j'ai 2 thread étant chacun connecté sur un serveur différent et que je reçois des messages des 2 serveurs. Soit je dois "recopier" les fonctions pour qu'ils ne s'appellent pas entre eux, soit les variables de résultats vont être complètement insignifiant.

    Un autre soucis serait que si j'ai 1 thread qui travaille sur un message et qu'un autre parse un autre message pendant que le 1er copie, le process du 1er thread sera foutu en l'air.

  4. #4
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Citation Envoyé par JulienDuSud Voir le message
    En gros, je souhaiterais après chaque parse réussi pouvoir récupérer les infos directement dans les membres du parser.
    Je n'ai pas trop d'expérience pratique de spirit, mais je pense voir le problème maintenant. En fait, tes différentes fonctions modifient un état global (ce qui effectivement posera des problèmes du multithread), état que tu tente de rendre moins global, mais qui reste en dehors du parseur lui même.

    Je pense que le plus simple serait de modifier la sémantique de ton parseur pour qu'au lieu de modifier un état global, il retourne simplement un objet, et que toutes les fonctions associées au parsing soient sans "side effects" (sauf éventuellement du log).

    Autrement, si tu veux continuer sur cette voie, je te conseille la lecture de http://spirit.sourceforge.net/distri...c/grammar.html et de l'exemple associé.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  5. #5
    Membre chevronné
    Inscrit en
    Août 2004
    Messages
    556
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 556
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    Je pense que le plus simple serait de modifier la sémantique de ton parseur pour qu'au lieu de modifier un état global, il retourne simplement un objet, et que toutes les fonctions associées au parsing soient sans "side effects" (sauf éventuellement du log).
    C'est exactement ce que je souhaite faire, malheureusement soit je lis de travers soit la documentation de spirit ne mentionne pas d'exemple concret sur comment le faire, et me lancer dans une étude complète des classes de spirit me prendrait trop de temps que pour faire une chose aussi triviale que ceci.

    Donc la question finale: est-il possible avec Spirit de séparer de manière cohérente et safe la sémantique de la grammaire ? Si oui, comment ? :\

  6. #6
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Salut,
    Je m'en suis sorti en utilisant phoenix, closure et lazy_parser.
    J'essaie d'en extraire un exemple simple et je le poste.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Parseur de multiple affectation (avec Boost.Spirit)
    Par Trademark dans le forum Langage
    Réponses: 5
    Dernier message: 16/07/2012, 19h20
  2. [BOOST.Spirit] Absence génante
    Par Invité2 dans le forum Boost
    Réponses: 27
    Dernier message: 10/10/2008, 12h45
  3. [BOOST.Spirit] Types de bases inéxistant
    Par Invité2 dans le forum Boost
    Réponses: 4
    Dernier message: 14/09/2008, 21h31
  4. Comment utiliser Boost::spirit ?
    Par kimels dans le forum Boost
    Réponses: 8
    Dernier message: 11/06/2008, 19h04
  5. find encapsulé afin d'exclure certains résultats
    Par soveste dans le forum Shell et commandes GNU
    Réponses: 3
    Dernier message: 29/01/2008, 09h39

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