123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- /*=============================================================================
- Copyright (c) 2011 Thomas Bernard
- http://spirit.sourceforge.net/
- 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)
- =============================================================================*/
- //[reference_includes
- #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_container.hpp>
- #include <boost/spirit/include/phoenix_object.hpp>
- #include <boost/spirit/include/phoenix_fusion.hpp>
- #include <boost/fusion/include/adapt_struct.hpp>
- #include <boost/spirit/repository/include/qi_kwd.hpp>
- #include <boost/spirit/repository/include/qi_keywords.hpp>
- #include <iostream>
- #include <string>
- #include <cstdlib>
- #include <iterator>
- //]
- // Data structure definitions
- struct base_type {
- base_type(const std::string &name) : name(name) {}
- std::string name;
-
- virtual std::ostream &output(std::ostream &os) const
- {
- os<<"Base : "<<name;
- return os;
- }
-
- };
- struct derived1 : public base_type {
- derived1(const std::string &name, unsigned int data1) : base_type(name), data1(data1) {}
- unsigned int data1;
- virtual std::ostream &output(std::ostream &os) const
- {
- base_type::output(os);
- os<<", "<<data1;
- return os;
- }
- };
- struct derived2 : public base_type {
- derived2(const std::string &name, unsigned int data2) : base_type(name), data2(data2) {}
- unsigned int data2;
- virtual std::ostream &output(std::ostream &os) const
- {
- base_type::output(os);
- os<<", "<<data2;
- return os;
- }
- };
- struct derived3 : public derived2 {
- derived3(const std::string &name, unsigned int data2, double data3) :
- derived2(name,data2),
- data3(data3) {}
- double data3;
- virtual std::ostream &output(std::ostream &os) const
- {
- derived2::output(os);
- os<<", "<<data3;
- return os;
- }
- };
- std::ostream &operator<<(std::ostream &os, const base_type &obj)
- {
- return obj.output(os);
- }
- BOOST_FUSION_ADAPT_STRUCT( base_type,
- (std::string, name)
- )
- BOOST_FUSION_ADAPT_STRUCT( derived1,
- (std::string , name)
- (unsigned int , data1)
- )
- BOOST_FUSION_ADAPT_STRUCT( derived2,
- (std::string , name)
- (unsigned int, data2)
- )
- BOOST_FUSION_ADAPT_STRUCT( derived3,
- (std::string , name)
- (unsigned int, data2)
- (double, data3)
- )
- //]
- int
- main()
- {
-
-
- using boost::spirit::repository::qi::kwd;
- using boost::spirit::qi::inf;
- using boost::spirit::ascii::space_type;
- using boost::spirit::ascii::char_;
- using boost::spirit::qi::double_;
- using boost::spirit::qi::int_;
- using boost::spirit::qi::rule;
- using boost::spirit::_val;
- using boost::spirit::_1;
- using boost::spirit::_2;
- using boost::spirit::_3;
-
-
- //Rule declarations
- rule<const char *, std::string(), space_type> parse_string;
- rule<const char *, std::vector<base_type*>(), space_type> kwd_rule;
-
- // Our string parsing helper
- parse_string %= '"'> *(char_-'"') > '"';
-
- namespace phx=boost::phoenix;
- //[ kwd rule
- kwd_rule =
- kwd("derived1")[ ('=' > parse_string > int_ ) [phx::push_back(_val,phx::new_<derived1>(_1,_2))] ]
- / kwd("derived2")[ ('=' > parse_string > int_ ) [phx::push_back(_val,phx::new_<derived2>(_1,_2))]]
- / kwd("derived3")[ ('=' > parse_string > int_ > double_) [phx::push_back(_val,phx::new_<derived3>(_1,_2,_3))] ]
- ;
- //]
-
- using boost::spirit::qi::phrase_parse;
- using boost::spirit::qi::ascii::space;
- // The result vector
- std::vector<base_type*> result;
-
- char const input[]="derived2 = \"object1\" 10 derived3= \"object2\" 40 20.0 ";
- char const* f(input);
- char const* l(f + strlen(f));
-
- if (phrase_parse(f, l, kwd_rule, space,result) && (f == l))
- std::cout << "ok" << std::endl;
- else
- std::cout << "fail" << std::endl;
- using namespace boost::phoenix::arg_names;
- std::for_each(result.begin(),result.end(),std::cout<<*arg1<<std::endl);
- // Clean up the vector of pointers
- std::for_each(result.begin(),result.end(),phx::delete_(arg1));
- return 0;
- }
|