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 :

Spirit + phoenix + closure


Sujet :

Boost C++

Vue hybride

3DArchi Spirit + phoenix + closure 07/10/2008, 15h56
3DArchi Bon, j'ai compris un truc: il... 08/10/2008, 12h52
3DArchi Hosanna 08/10/2008, 12h59
Message précédent Message précédent   Message suivant Message suivant
  1. #1
    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 Spirit + phoenix + closure
    Bonjour,
    En gros, dans ma grammaire j'ai un premier champs qui me dit le nombre d'éléments qui suivent. Je n'arrive pas à la construire: je n'arrive pas à faire le lien entre le nombre d'éléments lire et un parser repeat_p. J'essaye avec lazy_p mais je ne vois pas du tout comment tourner la chose. L'aide boost m'a été assez peu précieuse alors si quelque a une piste, je suis preneur.
    Code:
    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
    #include <iostream>
    #include <boost/spirit.hpp>
    #include <boost/spirit/dynamic/lazy.hpp>
    using namespace BOOST_SPIRIT_CLASSIC_NS;
    using namespace phoenix;
     
    struct ma_closure : boost::spirit::closure<ma_closure, size_t>
    {
      member1 NbrElts;
    };
     
     
    class MaGrammaire
       :public grammar<MaGrammaire>
    {
    public:
       template <typename ScannerT>
       struct definition
       {
          rule<ScannerT,ma_closure::context_t> liste;
          rule<ScannerT> element;
          definition(MaGrammaire const& self)
          {
             liste             = uint_p[assign_a(liste.NbrElts)]>>":">>lazy_p(repeat_p(liste.NbrElts)[element]);  // Comment faire?
             element           = uint_p>>",";
          }
          rule<ScannerT,ma_closure::context_t> const& start() const 
             {return liste;}
       };
    };
     
    int main()
    {
       MaGrammaire MonParseur;
     
       // Create a file iterator for this file
       std::string L_strChaine("5:1,2,3,4,5,");
       parse_info<char const*> info = parse(
            L_strChaine.c_str(),
            L_strChaine.c_str()+L_strChaine.length(),
            MonParseur
        );
        if (info.full)
            std::cout << "Parse succeeded!\n";
        else
            std::cout << "Parse failed!\n";
     
     
     
     
       return std::getc(stdin);
    }

  2. #2
    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
    Bon, j'ai compris un truc: il faut que penser 'Functional Programming', donc des foncteurs appropriés!
    J'ai donc rajouté un foncteur regle_lire_liste pour créer la règle à la volée. J'ai changé comme suit:
    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
    #include <boost/spirit.hpp>
    #include <boost/spirit/dynamic/lazy.hpp>
    using namespace BOOST_SPIRIT_CLASSIC_NS;
    using namespace phoenix;
     
    struct ma_closure : boost::spirit::closure<ma_closure, size_t>
    {
      member1 NbrElts;
    };
     
    class MaGrammaire
       :public grammar<MaGrammaire>
    {
    public:
       template <typename ScannerT>
       struct definition
       {
          template<typename TArg>
          struct regle_lire_liste
          {
             template<class Tuple>
             struct result
             {
                typedef rule<ScannerT> type;
             };
             explicit
                regle_lire_liste(definition &P_def,TArg& P_arg):m_def(P_def),m_arg(P_arg)
             {
             }
             rule<ScannerT> operator()()const
             {
                return repeat_p<size_t>(m_arg())[m_def.element];
             }
          protected:
             definition &m_def;
             TArg& m_arg;
             rule<ScannerT> m_regle;
          };
          template<class T>
          regle_lire_liste<T> regle_lire_liste_p(definition &P_def, T&P_arg)
          {
             return regle_lire_liste<T>(P_def,P_arg);
          }
          rule<ScannerT,ma_closure::context_t> liste;
          rule<ScannerT> element;
          rule<ScannerT> lire_liste;
     
          definition(MaGrammaire const& self)
          {
             liste             = uint_p[assign_a(liste.NbrElts)]>>":">>lire_liste;
             lire_liste        = lazy_p(regle_lire_liste_p(*this,liste.NbrElts));
             element           = uint_p>>",";
          }
          rule<ScannerT,ma_closure::context_t> const& start() const 
             {return liste;}
       };
    };
     
    #include <iostream>
    int main()
    {
       MaGrammaire MonParseur;
     
       // Create a file iterator for this file
       std::string L_strChaine("5:1,2,3,4,5,");
       parse_info<char const*> info = parse(
            L_strChaine.c_str(),
            L_strChaine.c_str()+L_strChaine.length(),
            MonParseur
        );
        if (info.full)
            std::cout << "Parse succeeded!\n";
        else
            std::cout << "Parse failed!\n";
     
     
     
     
       return std::getc(stdin);
    }
    Le problème maintenant c'est que je n'obtient pas de valeur correcte dans return repeat_p<size_t>(m_arg())[m_def.element]; pour m_arg. Il me renvoie n'importe quoi! Un piste?
    Merci d'avance car je sèche un peu!

  3. #3
    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 Hosanna
    Ben, fallait pousser le raisonnement jusqu'au bout! Le foncteur liste.NbrElts re définit l'opérateur d'affectation pour retourner un foncteur d'affectation (0-ary) lié entre l'espace de stockage de liste.NbrElts et la valeur extraite de uint_p. Donc, l'affectation à proprement parler n'est pas faite.
    Solution (provisoire?):
    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
    #include <boost/spirit.hpp>
    #include <boost/spirit/dynamic/lazy.hpp>
    using namespace BOOST_SPIRIT_CLASSIC_NS;
    using namespace phoenix;
    
    struct ma_closure : boost::spirit::closure<ma_closure, size_t>
    {
      member1 NbrElts;
    };
    
    class MaGrammaire
       :public grammar<MaGrammaire>
    {
    public:
       template <typename ScannerT>
       struct definition
       {
          template<typename TArg>
          struct regle_lire_liste
          {
             template<class Tuple>
             struct result
             {
                typedef rule<ScannerT> type;
             };
             explicit
                regle_lire_liste(definition &P_def,TArg& P_arg):m_def(P_def),m_arg(P_arg)
             {
             }
             rule<ScannerT> operator()()const
             {
                return repeat_p<size_t>(m_arg())[m_def.element];
             }
          protected:
             definition &m_def;
             TArg& m_arg;
             rule<ScannerT> m_regle;
          };
          template<class T>
          regle_lire_liste<T> regle_lire_liste_p(definition &P_def, T&P_arg)
          {
             return regle_lire_liste<T>(P_def,P_arg);
          }
          rule<ScannerT,ma_closure::context_t> liste;
          rule<ScannerT> element;
          rule<ScannerT> lire_liste;
    
          definition(MaGrammaire const& self)
          {
             liste             = uint_p[liste.NbrElts=arg1]>>":">>lire_liste;
             lire_liste        = lazy_p(regle_lire_liste_p(*this,liste.NbrElts));
             element           = uint_p>>",";
          }
          rule<ScannerT,ma_closure::context_t> const& start() const 
             {return liste;}
       };
    };
    
    #include <iostream>
    int main()
    {
       MaGrammaire MonParseur;
    
       // Create a file iterator for this file
       std::string L_strChaine("5:1,2,3,4,5,");
       parse_info<char const*> info = parse(
            L_strChaine.c_str(),
            L_strChaine.c_str()+L_strChaine.length(),
            MonParseur
        );
        if (info.full)
            std::cout << "Parse succeeded!\n";
        else
            std::cout << "Parse failed!\n";
    
    
    
    
       return std::getc(stdin);
    }

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

Discussions similaires

  1. Spirit : nécessité de connaître Phoenix ?
    Par oodini dans le forum Boost
    Réponses: 1
    Dernier message: 08/02/2014, 10h18
  2. [Spirit] utilisation de phoenix::ref et de bind
    Par niarkyzator dans le forum Boost
    Réponses: 2
    Dernier message: 20/05/2010, 13h06
  3. spirit et phoenix::bind
    Par 3DArchi dans le forum Boost
    Réponses: 5
    Dernier message: 09/10/2008, 10h55
  4. phoenix bios
    Par djibril dans le forum Composants
    Réponses: 14
    Dernier message: 17/12/2005, 17h51
  5. [C++]closure + héritage + transtypage
    Par JEG dans le forum C++Builder
    Réponses: 11
    Dernier message: 30/01/2004, 14h26

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