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 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
|
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
//#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/adapt_class.hpp>
#include <boost/fusion/include/io.hpp>
#include <iostream>
#include <string>
#include <complex>
namespace client
{
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
// Remplacement de la structure employee par une classe.
class employee
{
private:
int age;
std::string surname;
std::string forename;
double salary;
public:
employee(): age(0), surname(""), forename(""), salary(0.0) {};
virtual ~employee() {
}
int getAge() const {
return age;
}
void setAge(int age) {
this->age = age;
}
const std::string& getForename() const {
return forename;
}
void setForename(const std::string& forename) {
this->forename = forename;
}
double getSalary() const {
return salary;
}
void setSalary(double salary) {
this->salary = salary;
}
const std::string& getSurname() const {
return surname;
}
void setSurname(const std::string& surname) {
this->surname = surname;
}
};
} //namespace client
//*********************
// LA PARTIE QUI CHANGE
//*********************
BOOST_FUSION_ADAPT_CLASS(
client::employee,
(int, int, obj.getAge(), obj.setAge(val))
(const std::string&, const std::string&, obj.getSurname(), obj.setSurname(val))
(const std::string&, const std::string&, obj.getForename(), obj.setForename(val))
(double, double, obj.getSalary(), obj.setSalary(val))
)
namespace client
{
///////////////////////////////////////////////////////////////////////////////
// Our employee parser
///////////////////////////////////////////////////////////////////////////////
//[tutorial_employee_parser
template <typename Iterator>
struct employee_parser : qi::grammar<Iterator, employee(), ascii::space_type>
{
employee_parser() : employee_parser::base_type(start)
{
using qi::int_;
using qi::lit;
using qi::double_;
using qi::lexeme;
using ascii::char_;
quoted_string %= lexeme['"' >> +(char_ - '"') >> '"'];
start %=
lit("employee")
>> '{'
>> int_ >> ','
>> quoted_string >> ','
>> quoted_string >> ','
>> double_
>> '}'
;
}
qi::rule<Iterator, std::string(), ascii::space_type> quoted_string;
qi::rule<Iterator, employee(), ascii::space_type> start;
};
//]
}
////////////////////////////////////////////////////////////////////////////
// Main program
////////////////////////////////////////////////////////////////////////////
int
main()
{
std::cout << "/////////////////////////////////////////////////////////\n\n";
std::cout << "\t\tAn employee parser for Spirit...\n\n";
std::cout << "/////////////////////////////////////////////////////////\n\n";
std::cout
<< "Give me an employee of the form :"
<< "employee{age, \"surname\", \"forename\", salary } \n";
std::cout << "Type [q or Q] to quit\n\n";
using boost::spirit::ascii::space;
typedef std::string::const_iterator iterator_type;
typedef client::employee_parser<iterator_type> employee_parser;
employee_parser g; // Our grammar
std::string str;
while (getline(std::cin, str))
{
if (str.empty() || str[0] == 'q' || str[0] == 'Q')
break;
client::employee emp;
std::string::const_iterator iter = str.begin();
std::string::const_iterator end = str.end();
bool r = phrase_parse(iter, end, g, space, emp);
if (r && iter == end)
{
std::cout << boost::fusion::tuple_open('[');
std::cout << boost::fusion::tuple_close(']');
std::cout << boost::fusion::tuple_delimiter(", ");
std::cout << "-------------------------\n";
std::cout << "Parsing succeeded\n";
std::cout << "age: " << emp.getAge() << ", surname: " << emp.getSurname() << ", forename: " << emp.getForename() << ", salary: " << emp.getSalary() << std::endl;
// std::cout << "got: " << boost::fusion::as_vector(emp) << std::endl;
std::cout << "\n-------------------------\n";
}
else
{
std::cout << "-------------------------\n";
std::cout << "Parsing failed\n";
std::cout << "-------------------------\n";
}
}
std::cout << "Bye... :-) \n\n";
return 0;
} |
Partager