rule_parser_2_1.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. /*==============================================================================
  2. Copyright (c) 2002-2003 Joel de Guzman
  3. Copyright (c) 2006 Tobias Schwinger
  4. http://spirit.sourceforge.net/
  5. Use, modification and distribution is subject to the Boost Software
  6. License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  7. http://www.boost.org/LICENSE_1_0.txt)
  8. ==============================================================================*/
  9. //------------------------------------------------------------------------------
  10. // This example shows a recursive grammar built using subrules and typeof.
  11. // See boost/spirit/include/rule_parser.hpp for details.
  12. // This example is based on subrule_calc.cpp.
  13. //------------------------------------------------------------------------------
  14. #include <string>
  15. #include <iostream>
  16. #include <boost/typeof/typeof.hpp>
  17. #include <boost/spirit/include/classic_core.hpp>
  18. #include <boost/spirit/include/classic_typeof.hpp>
  19. #include <boost/spirit/include/classic_rule_parser.hpp>
  20. // Don't forget to
  21. #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
  22. using namespace BOOST_SPIRIT_CLASSIC_NS;
  23. // Semantic actions
  24. namespace
  25. {
  26. void do_int(int v) { std::cout << "PUSH(" << v << ')' << std::endl; }
  27. void do_add(char const*, char const*) { std::cout << "ADD" << std::endl; }
  28. void do_sub(char const*, char const*) { std::cout << "SUB" << std::endl; }
  29. void do_mul(char const*, char const*) { std::cout << "MUL" << std::endl; }
  30. void do_div(char const*, char const*) { std::cout << "DIV" << std::endl; }
  31. void do_neg(char const*, char const*) { std::cout << "NEG" << std::endl; }
  32. }
  33. // Operating at root namespace...
  34. #define BOOST_SPIRIT__NAMESPACE -
  35. // Our calculator grammar using subrules in a rule parser.
  36. BOOST_SPIRIT_RULE_PARSER( calc,
  37. -,
  38. -,
  39. (3,( ((subrule<0>),expression,()),
  40. ((subrule<1>),term,()),
  41. ((subrule<2>),factor,() )) ),
  42. (
  43. expression =
  44. term
  45. >> *( ('+' >> term)[&do_add]
  46. | ('-' >> term)[&do_sub]
  47. )
  48. ,
  49. term =
  50. factor
  51. >> *( ('*' >> factor)[&do_mul]
  52. | ('/' >> factor)[&do_div]
  53. )
  54. ,
  55. factor =
  56. int_p[&do_int]
  57. | ('(' >> expression >> ')')
  58. | ('-' >> factor)[&do_neg]
  59. | ('+' >> factor)
  60. )
  61. )
  62. #undef BOOST_SPIRIT__NAMESPACE
  63. // Main program
  64. int main()
  65. {
  66. std::cout
  67. << "/////////////////////////////////////////////////////////\n"
  68. << "\t\tA ruleless calculator using subrules...\n"
  69. << "/////////////////////////////////////////////////////////\n"
  70. << "Type an expression...or an empty line to quit\n"
  71. << std::endl;
  72. std::string str;
  73. while (std::getline(std::cin, str))
  74. {
  75. if (str.empty()) break;
  76. parse_info<> info = parse(str.c_str(), calc, space_p);
  77. if (info.full)
  78. std::cout
  79. << "OK."
  80. << std::endl;
  81. else
  82. std::cout
  83. << "ERROR.\n"
  84. << "Stopped at: \": " << info.stop << "\".\n"
  85. << std::endl;
  86. }
  87. return 0;
  88. }