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 83 84 85 86 87 88 89 90 91
   | #include <boost/spirit.hpp>
#include <boost/spirit/dynamic/lazy.hpp>
#include <boost/spirit/phoenix.hpp>
using namespace BOOST_SPIRIT_CLASSIC_NS;
using namespace phoenix;
// actor pour la creation de règles paramétrées par 1 argument:
template<typename TRetour, typename TLazyRegle, typename TArg>
struct regle_lazy
{
   template<class Tuple> struct result {typedef TRetour type;};
   regle_lazy(TLazyRegle P_regle,TArg& P_arg):m_regle(P_regle),m_arg(P_arg)
   {
   }
   TRetour operator()()const
   {// on appele la regle avec l'évaluation de l'argument
      return m_regle(m_arg());
   }
protected:
   TLazyRegle m_regle;
   TArg& m_arg;
};
// méthode pour construire facilement une règle_lazy:
template<class TRetour, class TRegle, class TArg>
regle_lazy<TRetour,TRegle,TArg> regle_lazy_p(const TRegle &P_regle, TArg&P_arg)
{
   return regle_lazy<TRetour, TRegle, TArg>(P_regle,P_arg);
}
class MaGrammaire
   :public grammar<MaGrammaire>
{
public:
   // définition de la structure closure pour les variables associées aux règles:
   struct variable_taille : boost::spirit::closure<variable_taille, size_t>
   {
     member1 NbrElts;
   };
   template <typename ScannerT>
   struct definition
   {
      template <typename ExactT>
      static fixed_loop_gen <ExactT>
      generer_repeat_p(ExactT const & exact)
      {
        return repeat_p(exact);
      }
      // définition de la grammaire:
      definition(MaGrammaire const& self)
      {
         liste             = uint_p[liste.NbrElts=arg1]>>":">>lire_liste;
         lire_liste        = lazy_p( regle_lazy_p<rule<ScannerT> >(
                  phoenix::bind(&fixed_loop_gen<size_t>::operator[]<rule<ScannerT> >)(phoenix::bind(&generer_repeat_p<size_t>)(arg1),var(element))
                  ,liste.NbrElts
               )
            );
         element           = uint_p>>",";
      }
      // définition de la racine:
      rule<ScannerT,typename variable_taille::context_t> const& start() const
         {return liste;}
   protected:
      // les règles:
      rule<ScannerT,typename variable_taille::context_t> liste;
      rule<ScannerT> element;
      rule<ScannerT> lire_liste;
   };
};
#include <iostream>
int main()
{
   MaGrammaire MonParseur;
   std::string L_strChaine("6:1,2,3,4,5,6,");
   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);
} | 
Partager