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