calc_plain.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /*=============================================================================
  2. Copyright (c) 2002-2003 Joel de Guzman
  3. http://spirit.sourceforge.net/
  4. Use, modification and distribution is subject to the Boost Software
  5. License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  6. http://www.boost.org/LICENSE_1_0.txt)
  7. =============================================================================*/
  8. ////////////////////////////////////////////////////////////////////////////
  9. //
  10. // Plain calculator example demostrating the grammar and semantic actions.
  11. // This is discussed in the "Grammar" and "Semantic Actions" chapters in
  12. // the Spirit User's Guide.
  13. //
  14. // [ JDG 5/10/2002 ]
  15. //
  16. ////////////////////////////////////////////////////////////////////////////
  17. #include <boost/spirit/include/classic_core.hpp>
  18. #include <iostream>
  19. #include <string>
  20. ////////////////////////////////////////////////////////////////////////////
  21. using namespace std;
  22. using namespace BOOST_SPIRIT_CLASSIC_NS;
  23. ////////////////////////////////////////////////////////////////////////////
  24. //
  25. // Semantic actions
  26. //
  27. ////////////////////////////////////////////////////////////////////////////
  28. namespace
  29. {
  30. void do_int(char const* str, char const* end)
  31. {
  32. string s(str, end);
  33. cout << "PUSH(" << s << ')' << endl;
  34. }
  35. void do_add(char const*, char const*) { cout << "ADD\n"; }
  36. void do_subt(char const*, char const*) { cout << "SUBTRACT\n"; }
  37. void do_mult(char const*, char const*) { cout << "MULTIPLY\n"; }
  38. void do_div(char const*, char const*) { cout << "DIVIDE\n"; }
  39. void do_neg(char const*, char const*) { cout << "NEGATE\n"; }
  40. }
  41. ////////////////////////////////////////////////////////////////////////////
  42. //
  43. // Our calculator grammar
  44. //
  45. ////////////////////////////////////////////////////////////////////////////
  46. struct calculator : public grammar<calculator>
  47. {
  48. template <typename ScannerT>
  49. struct definition
  50. {
  51. definition(calculator const& /*self*/)
  52. {
  53. expression
  54. = term
  55. >> *( ('+' >> term)[&do_add]
  56. | ('-' >> term)[&do_subt]
  57. )
  58. ;
  59. term
  60. = factor
  61. >> *( ('*' >> factor)[&do_mult]
  62. | ('/' >> factor)[&do_div]
  63. )
  64. ;
  65. factor
  66. = lexeme_d[(+digit_p)[&do_int]]
  67. | '(' >> expression >> ')'
  68. | ('-' >> factor)[&do_neg]
  69. | ('+' >> factor)
  70. ;
  71. }
  72. rule<ScannerT> expression, term, factor;
  73. rule<ScannerT> const&
  74. start() const { return expression; }
  75. };
  76. };
  77. ////////////////////////////////////////////////////////////////////////////
  78. //
  79. // Main program
  80. //
  81. ////////////////////////////////////////////////////////////////////////////
  82. int
  83. main()
  84. {
  85. cout << "/////////////////////////////////////////////////////////\n\n";
  86. cout << "\t\tExpression parser...\n\n";
  87. cout << "/////////////////////////////////////////////////////////\n\n";
  88. cout << "Type an expression...or [q or Q] to quit\n\n";
  89. calculator calc; // Our parser
  90. string str;
  91. while (getline(cin, str))
  92. {
  93. if (str.empty() || str[0] == 'q' || str[0] == 'Q')
  94. break;
  95. parse_info<> info = parse(str.c_str(), calc, space_p);
  96. if (info.full)
  97. {
  98. cout << "-------------------------\n";
  99. cout << "Parsing succeeded\n";
  100. cout << "-------------------------\n";
  101. }
  102. else
  103. {
  104. cout << "-------------------------\n";
  105. cout << "Parsing failed\n";
  106. cout << "stopped at: \": " << info.stop << "\"\n";
  107. cout << "-------------------------\n";
  108. }
  109. }
  110. cout << "Bye... :-) \n\n";
  111. return 0;
  112. }