employee.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /*=============================================================================
  2. Copyright (c) 2002-2010 Joel de Guzman
  3. Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. =============================================================================*/
  6. ///////////////////////////////////////////////////////////////////////////////
  7. //
  8. // A parser for arbitrary tuples. This example presents a parser
  9. // for an employee structure.
  10. //
  11. // [ JDG May 9, 2007 ]
  12. //
  13. ///////////////////////////////////////////////////////////////////////////////
  14. #include <boost/config/warning_disable.hpp>
  15. #include <boost/spirit/include/qi.hpp>
  16. #include <boost/spirit/include/phoenix_core.hpp>
  17. #include <boost/spirit/include/phoenix_operator.hpp>
  18. #include <boost/spirit/include/phoenix_object.hpp>
  19. #include <boost/fusion/include/adapt_struct.hpp>
  20. #include <boost/fusion/include/io.hpp>
  21. #include <iostream>
  22. #include <string>
  23. #include <complex>
  24. namespace client
  25. {
  26. namespace qi = boost::spirit::qi;
  27. namespace ascii = boost::spirit::ascii;
  28. ///////////////////////////////////////////////////////////////////////////
  29. // Our employee struct
  30. ///////////////////////////////////////////////////////////////////////////
  31. //[tutorial_employee_struct
  32. struct employee
  33. {
  34. int age;
  35. std::string surname;
  36. std::string forename;
  37. double salary;
  38. };
  39. //]
  40. }
  41. // We need to tell fusion about our employee struct
  42. // to make it a first-class fusion citizen. This has to
  43. // be in global scope.
  44. //[tutorial_employee_adapt_struct
  45. BOOST_FUSION_ADAPT_STRUCT(
  46. client::employee,
  47. (int, age)
  48. (std::string, surname)
  49. (std::string, forename)
  50. (double, salary)
  51. )
  52. //]
  53. namespace client
  54. {
  55. ///////////////////////////////////////////////////////////////////////////////
  56. // Our employee parser
  57. ///////////////////////////////////////////////////////////////////////////////
  58. //[tutorial_employee_parser
  59. template <typename Iterator>
  60. struct employee_parser : qi::grammar<Iterator, employee(), ascii::space_type>
  61. {
  62. employee_parser() : employee_parser::base_type(start)
  63. {
  64. using qi::int_;
  65. using qi::lit;
  66. using qi::double_;
  67. using qi::lexeme;
  68. using ascii::char_;
  69. quoted_string %= lexeme['"' >> +(char_ - '"') >> '"'];
  70. start %=
  71. lit("employee")
  72. >> '{'
  73. >> int_ >> ','
  74. >> quoted_string >> ','
  75. >> quoted_string >> ','
  76. >> double_
  77. >> '}'
  78. ;
  79. }
  80. qi::rule<Iterator, std::string(), ascii::space_type> quoted_string;
  81. qi::rule<Iterator, employee(), ascii::space_type> start;
  82. };
  83. //]
  84. }
  85. ////////////////////////////////////////////////////////////////////////////
  86. // Main program
  87. ////////////////////////////////////////////////////////////////////////////
  88. int
  89. main()
  90. {
  91. std::cout << "/////////////////////////////////////////////////////////\n\n";
  92. std::cout << "\t\tAn employee parser for Spirit...\n\n";
  93. std::cout << "/////////////////////////////////////////////////////////\n\n";
  94. std::cout
  95. << "Give me an employee of the form :"
  96. << "employee{age, \"surname\", \"forename\", salary } \n";
  97. std::cout << "Type [q or Q] to quit\n\n";
  98. using boost::spirit::ascii::space;
  99. typedef std::string::const_iterator iterator_type;
  100. typedef client::employee_parser<iterator_type> employee_parser;
  101. employee_parser g; // Our grammar
  102. std::string str;
  103. while (getline(std::cin, str))
  104. {
  105. if (str.empty() || str[0] == 'q' || str[0] == 'Q')
  106. break;
  107. client::employee emp;
  108. std::string::const_iterator iter = str.begin();
  109. std::string::const_iterator end = str.end();
  110. bool r = phrase_parse(iter, end, g, space, emp);
  111. if (r && iter == end)
  112. {
  113. std::cout << boost::fusion::tuple_open('[');
  114. std::cout << boost::fusion::tuple_close(']');
  115. std::cout << boost::fusion::tuple_delimiter(", ");
  116. std::cout << "-------------------------\n";
  117. std::cout << "Parsing succeeded\n";
  118. std::cout << "got: " << boost::fusion::as_vector(emp) << std::endl;
  119. std::cout << "\n-------------------------\n";
  120. }
  121. else
  122. {
  123. std::cout << "-------------------------\n";
  124. std::cout << "Parsing failed\n";
  125. std::cout << "-------------------------\n";
  126. }
  127. }
  128. std::cout << "Bye... :-) \n\n";
  129. return 0;
  130. }