// Copyright (c) 2001-2010 Hartmut Kaiser // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // The main purpose of this example is to show how a single fusion sequence // can be filled from a parsed input of the elements in different sequences #include #include #include #include #include #include namespace fusion = boost::fusion; namespace qi = boost::spirit::qi; /////////////////////////////////////////////////////////////////////////////// namespace client { // Our employee struct struct employee { std::string surname; std::string forename; int age; double salary; std::string department; }; // define iterator type typedef std::string::const_iterator iterator_type; // This is the output routine taking a format description and the data to // print template bool parse(std::string const& input, Parser const& p, Sequence& s) { iterator_type begin = input.begin(); return qi::parse(begin, input.end(), p, s); } } // We need to tell fusion about our employee struct to make it a first-class // fusion citizen. This has to be in global scope. Note that we don't need to // list the members of our struct in the same sequence a they are defined BOOST_FUSION_ADAPT_STRUCT( client::employee, (int, age) (std::string, surname) (std::string, forename) (std::string, department) (double, salary) ) /////////////////////////////////////////////////////////////////////////////// // that's the different types we need to reorder the attributes typedef fusion::result_of::as_nview::type name_and_age; typedef fusion::result_of::as_nview::type names_and_salary; typedef fusion::result_of::as_nview::type name_age_and_department; /////////////////////////////////////////////////////////////////////////////// int main() { std::string str; // some employees client::employee john; client::employee mary; client::employee tom; // print data about employees in different formats { // parse forename and age only name_and_age johnview(fusion::as_nview<2, 0>(john)); bool r = client::parse( "John, 25", *(qi::char_ - ',') >> ", " >> qi::int_, johnview); if (r) { std::cout << "Parsed: " << john.forename << ", " << john.age << std::endl; } // parse surname, forename, and salary names_and_salary maryview(fusion::as_nview<1, 2, 4>(mary)); r = client::parse( "Higgins, Mary: 2200.36", *(qi::char_ - ',') >> ", " >> *(qi::char_ - ':') >> ": " >> qi::double_, maryview); if (r) { std::cout << "Parsed: " << mary.forename << ", " << mary.surname << ", " << mary.salary << std::endl; } // parse forename, age, and department name_age_and_department tomview(fusion::as_nview<2, 0, 3>(tom)); client::parse( "Tom: 48 (Boss)", *(qi::char_ - ':') >> ": " >> qi::int_ >> " (" >> *(qi::char_ - ')') >> ')', tomview); if (r) { std::cout << "Parsed: " << tom.forename << ", " << tom.age << ", " << tom.department << std::endl; } } // now parse a list of several employees and print them all std::vector employees; // parse surname, forename, and salary for all employees { qi::rule r = *(qi::char_ - ',') >> ", " >> *(qi::char_ - ',') >> ", " >> qi::double_; bool result = client::parse( "John, Smith, 2000.50\n" "Mary, Higgins, 2200.36\n" "Tom, Taylor, 3200.00\n", r % qi::eol, employees); std::cout << "Parsed: " << std::endl; BOOST_FOREACH(client::employee const& e, employees) { std::cout << e.forename << ", " << e.surname << ", " << e.salary << std::endl; } } return 0; }