123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- // 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 <boost/config/warning_disable.hpp>
- #include <boost/mpl/print.hpp>
- #include <boost/spirit/include/qi.hpp>
- #include <boost/fusion/include/struct.hpp>
- #include <boost/fusion/include/nview.hpp>
- #include <boost/foreach.hpp>
- 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 <typename Parser, typename Sequence>
- 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<client::employee, 2, 0>::type name_and_age;
- typedef fusion::result_of::as_nview<client::employee, 1, 2, 4>::type names_and_salary;
- typedef fusion::result_of::as_nview<client::employee, 2, 0, 3>::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<client::employee> employees;
- // parse surname, forename, and salary for all employees
- {
- qi::rule<client::iterator_type, names_and_salary()> 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;
- }
|