blob: a92490a989a4b98b1fd58facea6ca88cf52003dc [file] [log] [blame]
/*=============================================================================
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;
}