employee.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /*=============================================================================
  2. Copyright (c) 2002-2015 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. // [ JDG May 13, 2015 ] spirit X3
  13. //
  14. ///////////////////////////////////////////////////////////////////////////////
  15. #include <boost/config/warning_disable.hpp>
  16. #include <boost/spirit/home/x3.hpp>
  17. #include <boost/fusion/include/adapt_struct.hpp>
  18. #include <boost/fusion/include/io.hpp>
  19. #include <iostream>
  20. #include <string>
  21. namespace client { namespace ast
  22. {
  23. ///////////////////////////////////////////////////////////////////////////
  24. // Our employee struct
  25. ///////////////////////////////////////////////////////////////////////////
  26. struct employee
  27. {
  28. int age;
  29. std::string forename;
  30. std::string surname;
  31. double salary;
  32. };
  33. using boost::fusion::operator<<;
  34. }}
  35. // We need to tell fusion about our employee struct
  36. // to make it a first-class fusion citizen. This has to
  37. // be in global scope.
  38. BOOST_FUSION_ADAPT_STRUCT(client::ast::employee,
  39. age, forename, surname, salary
  40. )
  41. namespace client
  42. {
  43. ///////////////////////////////////////////////////////////////////////////////
  44. // Our employee parser
  45. ///////////////////////////////////////////////////////////////////////////////
  46. namespace parser
  47. {
  48. namespace x3 = boost::spirit::x3;
  49. namespace ascii = boost::spirit::x3::ascii;
  50. using x3::int_;
  51. using x3::lit;
  52. using x3::double_;
  53. using x3::lexeme;
  54. using ascii::char_;
  55. x3::rule<class employee, ast::employee> const employee = "employee";
  56. auto const quoted_string = lexeme['"' >> +(char_ - '"') >> '"'];
  57. auto const employee_def =
  58. lit("employee")
  59. >> '{'
  60. >> int_ >> ','
  61. >> quoted_string >> ','
  62. >> quoted_string >> ','
  63. >> double_
  64. >> '}'
  65. ;
  66. BOOST_SPIRIT_DEFINE(employee);
  67. }
  68. }
  69. ////////////////////////////////////////////////////////////////////////////
  70. // Main program
  71. ////////////////////////////////////////////////////////////////////////////
  72. int
  73. main()
  74. {
  75. std::cout << "/////////////////////////////////////////////////////////\n\n";
  76. std::cout << "\t\tAn employee parser for Spirit...\n\n";
  77. std::cout << "/////////////////////////////////////////////////////////\n\n";
  78. std::cout
  79. << "Give me an employee of the form :"
  80. << "employee{age, \"forename\", \"surname\", salary } \n";
  81. std::cout << "Type [q or Q] to quit\n\n";
  82. using boost::spirit::x3::ascii::space;
  83. typedef std::string::const_iterator iterator_type;
  84. using client::parser::employee;
  85. std::string str;
  86. while (getline(std::cin, str))
  87. {
  88. if (str.empty() || str[0] == 'q' || str[0] == 'Q')
  89. break;
  90. client::ast::employee emp;
  91. iterator_type iter = str.begin();
  92. iterator_type const end = str.end();
  93. bool r = phrase_parse(iter, end, employee, space, emp);
  94. if (r && iter == end)
  95. {
  96. std::cout << boost::fusion::tuple_open('[');
  97. std::cout << boost::fusion::tuple_close(']');
  98. std::cout << boost::fusion::tuple_delimiter(", ");
  99. std::cout << "-------------------------\n";
  100. std::cout << "Parsing succeeded\n";
  101. std::cout << "got: " << emp << std::endl;
  102. std::cout << "\n-------------------------\n";
  103. }
  104. else
  105. {
  106. std::cout << "-------------------------\n";
  107. std::cout << "Parsing failed\n";
  108. std::cout << "-------------------------\n";
  109. }
  110. }
  111. std::cout << "Bye... :-) \n\n";
  112. return 0;
  113. }