derived.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /*=============================================================================
  2. Copyright (c) 2011 Thomas Bernard
  3. http://spirit.sourceforge.net/
  4. Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. =============================================================================*/
  7. //[reference_includes
  8. #include <boost/spirit/include/qi.hpp>
  9. #include <boost/spirit/include/phoenix_core.hpp>
  10. #include <boost/spirit/include/phoenix_operator.hpp>
  11. #include <boost/spirit/include/phoenix_container.hpp>
  12. #include <boost/spirit/include/phoenix_object.hpp>
  13. #include <boost/spirit/include/phoenix_fusion.hpp>
  14. #include <boost/fusion/include/adapt_struct.hpp>
  15. #include <boost/spirit/repository/include/qi_kwd.hpp>
  16. #include <boost/spirit/repository/include/qi_keywords.hpp>
  17. #include <iostream>
  18. #include <string>
  19. #include <cstdlib>
  20. #include <iterator>
  21. //]
  22. // Data structure definitions
  23. struct base_type {
  24. base_type(const std::string &name) : name(name) {}
  25. std::string name;
  26. virtual std::ostream &output(std::ostream &os) const
  27. {
  28. os<<"Base : "<<name;
  29. return os;
  30. }
  31. };
  32. struct derived1 : public base_type {
  33. derived1(const std::string &name, unsigned int data1) : base_type(name), data1(data1) {}
  34. unsigned int data1;
  35. virtual std::ostream &output(std::ostream &os) const
  36. {
  37. base_type::output(os);
  38. os<<", "<<data1;
  39. return os;
  40. }
  41. };
  42. struct derived2 : public base_type {
  43. derived2(const std::string &name, unsigned int data2) : base_type(name), data2(data2) {}
  44. unsigned int data2;
  45. virtual std::ostream &output(std::ostream &os) const
  46. {
  47. base_type::output(os);
  48. os<<", "<<data2;
  49. return os;
  50. }
  51. };
  52. struct derived3 : public derived2 {
  53. derived3(const std::string &name, unsigned int data2, double data3) :
  54. derived2(name,data2),
  55. data3(data3) {}
  56. double data3;
  57. virtual std::ostream &output(std::ostream &os) const
  58. {
  59. derived2::output(os);
  60. os<<", "<<data3;
  61. return os;
  62. }
  63. };
  64. std::ostream &operator<<(std::ostream &os, const base_type &obj)
  65. {
  66. return obj.output(os);
  67. }
  68. BOOST_FUSION_ADAPT_STRUCT( base_type,
  69. (std::string, name)
  70. )
  71. BOOST_FUSION_ADAPT_STRUCT( derived1,
  72. (std::string , name)
  73. (unsigned int , data1)
  74. )
  75. BOOST_FUSION_ADAPT_STRUCT( derived2,
  76. (std::string , name)
  77. (unsigned int, data2)
  78. )
  79. BOOST_FUSION_ADAPT_STRUCT( derived3,
  80. (std::string , name)
  81. (unsigned int, data2)
  82. (double, data3)
  83. )
  84. //]
  85. int
  86. main()
  87. {
  88. using boost::spirit::repository::qi::kwd;
  89. using boost::spirit::qi::inf;
  90. using boost::spirit::ascii::space_type;
  91. using boost::spirit::ascii::char_;
  92. using boost::spirit::qi::double_;
  93. using boost::spirit::qi::int_;
  94. using boost::spirit::qi::rule;
  95. using boost::spirit::_val;
  96. using boost::spirit::_1;
  97. using boost::spirit::_2;
  98. using boost::spirit::_3;
  99. //Rule declarations
  100. rule<const char *, std::string(), space_type> parse_string;
  101. rule<const char *, std::vector<base_type*>(), space_type> kwd_rule;
  102. // Our string parsing helper
  103. parse_string %= '"'> *(char_-'"') > '"';
  104. namespace phx=boost::phoenix;
  105. //[ kwd rule
  106. kwd_rule =
  107. kwd("derived1")[ ('=' > parse_string > int_ ) [phx::push_back(_val,phx::new_<derived1>(_1,_2))] ]
  108. / kwd("derived2")[ ('=' > parse_string > int_ ) [phx::push_back(_val,phx::new_<derived2>(_1,_2))]]
  109. / kwd("derived3")[ ('=' > parse_string > int_ > double_) [phx::push_back(_val,phx::new_<derived3>(_1,_2,_3))] ]
  110. ;
  111. //]
  112. using boost::spirit::qi::phrase_parse;
  113. using boost::spirit::qi::ascii::space;
  114. // The result vector
  115. std::vector<base_type*> result;
  116. char const input[]="derived2 = \"object1\" 10 derived3= \"object2\" 40 20.0 ";
  117. char const* f(input);
  118. char const* l(f + strlen(f));
  119. if (phrase_parse(f, l, kwd_rule, space,result) && (f == l))
  120. std::cout << "ok" << std::endl;
  121. else
  122. std::cout << "fail" << std::endl;
  123. using namespace boost::phoenix::arg_names;
  124. std::for_each(result.begin(),result.end(),std::cout<<*arg1<<std::endl);
  125. // Clean up the vector of pointers
  126. std::for_each(result.begin(),result.end(),phx::delete_(arg1));
  127. return 0;
  128. }