calc1.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /*=============================================================================
  2. Copyright (c) 2001-2014 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. // Plain calculator example demonstrating the grammar. The parser is a
  9. // syntax checker only and does not do any semantic evaluation.
  10. //
  11. // [ JDG May 10, 2002 ] spirit 1
  12. // [ JDG March 4, 2007 ] spirit 2
  13. // [ JDG February 21, 2011 ] spirit 2.5
  14. // [ JDG June 6, 2014 ] spirit x3
  15. //
  16. ///////////////////////////////////////////////////////////////////////////////
  17. #include <boost/config/warning_disable.hpp>
  18. #include <boost/spirit/home/x3.hpp>
  19. #include <boost/spirit/home/x3/support/ast/variant.hpp>
  20. #include <boost/fusion/include/adapt_struct.hpp>
  21. #include <iostream>
  22. #include <string>
  23. #include <list>
  24. #include <numeric>
  25. namespace x3 = boost::spirit::x3;
  26. namespace client
  27. {
  28. ///////////////////////////////////////////////////////////////////////////////
  29. // The calculator grammar
  30. ///////////////////////////////////////////////////////////////////////////////
  31. namespace calculator_grammar
  32. {
  33. using x3::uint_;
  34. using x3::char_;
  35. x3::rule<class expression> const expression("expression");
  36. x3::rule<class term> const term("term");
  37. x3::rule<class factor> const factor("factor");
  38. auto const expression_def =
  39. term
  40. >> *( ('+' >> term)
  41. | ('-' >> term)
  42. )
  43. ;
  44. auto const term_def =
  45. factor
  46. >> *( ('*' >> factor)
  47. | ('/' >> factor)
  48. )
  49. ;
  50. auto const factor_def =
  51. uint_
  52. | '(' >> expression >> ')'
  53. | ('-' >> factor)
  54. | ('+' >> factor)
  55. ;
  56. BOOST_SPIRIT_DEFINE(
  57. expression
  58. , term
  59. , factor
  60. );
  61. auto calculator = expression;
  62. }
  63. using calculator_grammar::calculator;
  64. }
  65. ///////////////////////////////////////////////////////////////////////////////
  66. // Main program
  67. ///////////////////////////////////////////////////////////////////////////////
  68. int
  69. main()
  70. {
  71. std::cout << "/////////////////////////////////////////////////////////\n\n";
  72. std::cout << "Expression parser...\n\n";
  73. std::cout << "/////////////////////////////////////////////////////////\n\n";
  74. std::cout << "Type an expression...or [q or Q] to quit\n\n";
  75. typedef std::string::const_iterator iterator_type;
  76. std::string str;
  77. while (std::getline(std::cin, str))
  78. {
  79. if (str.empty() || str[0] == 'q' || str[0] == 'Q')
  80. break;
  81. auto& calc = client::calculator; // Our grammar
  82. iterator_type iter = str.begin();
  83. iterator_type end = str.end();
  84. boost::spirit::x3::ascii::space_type space;
  85. bool r = phrase_parse(iter, end, calc, space);
  86. if (r && iter == end)
  87. {
  88. std::cout << "-------------------------\n";
  89. std::cout << "Parsing succeeded\n";
  90. std::cout << "-------------------------\n";
  91. }
  92. else
  93. {
  94. std::string rest(iter, end);
  95. std::cout << "-------------------------\n";
  96. std::cout << "Parsing failed\n";
  97. std::cout << "stopped at: \"" << rest << "\"\n";
  98. std::cout << "-------------------------\n";
  99. }
  100. }
  101. std::cout << "Bye... :-) \n\n";
  102. return 0;
  103. }