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 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
| #include <string>
#include <iostream>
#include <boost/spirit/include/classic_core.hpp>
// la base de spirit
#include <boost/spirit/include/classic_attribute.hpp>
// pour permettre les closures
#include <boost/spirit/include/phoenix1.hpp>
// pour permettre le bind
using namespace BOOST_SPIRIT_CLASSIC_NS;
using namespace phoenix;
using namespace std;
// cette structure va nous servir à recevoir le résultat du parse
// j'ai repris ce que tu avais fait et l'ai juste sorti de la structure :
struct stIRCResultat
{
string snick;
string shost;
string stype;
string sarg;
string sinfo;
void nick_f( std::string const & val_) { snick = val_; }
void host_f( std::string const & val_) { shost = val_; }
void type_f( std::string const & val_) { stype = val_; }
void arg_f( std::string const & val_) { sarg = val_; }
void info_f( std::string const & val_) { sinfo = val_; }
};
// la structure qui permet d'associer un paramètre à une règle :
// le second template est le type du paramètre :
struct IRCParser_closure : boost::spirit::classic::closure<IRCParser_closure, stIRCResultat>
{
member1 variable_1;
};
// ta grammaire :
struct IRCParser : public grammar<IRCParser, IRCParser_closure::context_t>
{
// j'ai mis le resultat dans la grammaire au vu de ce que j'ai compris de ton fil
// mais, il aurait été plus logique de le passer en parametre (cf ci dessous)
stIRCResultat m_resultat;
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)[
phoenix::bind(&stIRCResultat::nick_f)(self.variable_1,phoenix::construct_<std::string>(arg1, arg2))
]// l'action déclanchée consiste à appeler la méthode avec le résultat du parser (+alnum_p) sur l'objet parametre de la règle
>> ch_p('!')
;
host
=
(
+alnum_p
>> ch_p('@')
>> +alnum_p
>> ch_p('.')
>> +alnum_p
)[
phoenix::bind(&stIRCResultat::host_f)(self.variable_1,phoenix::construct_<std::string>(arg1, arg2))
]
//[&this->host_f] <==== Erreur
;
type
=
(+upper_p)[
phoenix::bind(&stIRCResultat::type_f)(self.variable_1,phoenix::construct_<std::string>(arg1, arg2))
]//[&this->type_f] <==== Erreur
;
argument
=
(+(anychar_p - ':'))[
phoenix::bind(&stIRCResultat::arg_f)(self.variable_1,phoenix::construct_<std::string>(arg1, arg2))
]//[&this->arg_f] <==== Erreur
;
info
= (*anychar_p)[
phoenix::bind(&stIRCResultat::info_f)(self.variable_1,phoenix::construct_<std::string>(arg1, arg2))
]//[&this->info_f] <==== Erreur
;
}
rule<ScannerT> message, nick, host, type, argument, info;
rule<ScannerT> const& start() const
{
return message;
}
};
};
int main()
{
IRCParser r;
string str = ":Nick!Host@name.here JOIN :#channel";
parse( str.c_str(), r[var(r.m_resultat) = arg1]);
std::cout
<<r.m_resultat.snick<<std::endl
<<r.m_resultat.shost<<std::endl
<<r.m_resultat.stype<<std::endl
<<r.m_resultat.sarg<<std::endl
<<r.m_resultat.sinfo<<std::endl
;
// en fait, il est certainement plus approprie de sortir le resultat
// de la grammaire (suppression de la variable membre m_resultat)
// et d'utiliser une variable locale comme résultat du parse :
stIRCResultat resultat;
parse( str.c_str(), r[var(resultat) = arg1]);
std::cout
<<resultat.snick<<std::endl
<<resultat.shost<<std::endl
<<resultat.stype<<std::endl
<<resultat.sarg<<std::endl
<<resultat.sinfo<<std::endl
;
return 0;
} |
Partager