#include #include #include #include #include #include #include #include #include #include namespace client { namespace qi = boost::spirit::qi; namespace ascii = boost::spirit::ascii; /////////////////////////////////////////////////////////////////////////// // Our employee struct /////////////////////////////////////////////////////////////////////////// //[tutorial_employee_struct struct employee { int age; /* std::string surname; std::string forename; double salary; */ }; //] } // We need to tell fusion about our employee struct // to make it a first-class fusion citizen. This has to // be in global scope. //[tutorial_employee_adapt_struct BOOST_FUSION_ADAPT_STRUCT( client::employee, (int, age) /* (std::string, surname) (std::string, forename) (double, salary) */ ) //] namespace client { /////////////////////////////////////////////////////////////////////////////// // Our employee parser /////////////////////////////////////////////////////////////////////////////// //[tutorial_employee_parser template struct employee_parser : qi::grammar { 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 quoted_string; qi::rule 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 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 << "got: " << boost::fusion::as_vector(emp) << std::endl; std::cout << "\n-------------------------\n"; } else { std::cout << "-------------------------\n"; std::cout << "Parsing failed\n"; std::cout << "-------------------------\n"; } } return 0; }