123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- /*=============================================================================
- Copyright (c) 2002-2010 Joel de Guzman
- 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)
- =============================================================================*/
- ///////////////////////////////////////////////////////////////////////////////
- //
- // A parser for arbitrary tuples. This example presents a parser
- // for an employee structure.
- //
- // [ JDG May 9, 2007 ]
- //
- ///////////////////////////////////////////////////////////////////////////////
- #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/io.hpp>
- #include <iostream>
- #include <string>
- #include <complex>
- 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 <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 << "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;
- }
|