calc1_sr.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /*=============================================================================
  2. Copyright (c) 2001-2010 Joel de Guzman
  3. Copyright (c) 2009 Francois Barel
  4. Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. =============================================================================*/
  7. ///////////////////////////////////////////////////////////////////////////////
  8. //
  9. // Plain calculator example demonstrating the grammar. The parser is a
  10. // syntax checker only and does not do any semantic evaluation.
  11. //
  12. // [ JDG May 10, 2002 ] spirit1
  13. // [ JDG March 4, 2007 ] spirit2
  14. //
  15. ///////////////////////////////////////////////////////////////////////////////
  16. #include <boost/config/warning_disable.hpp>
  17. #include <boost/spirit/include/qi.hpp>
  18. #include <boost/spirit/repository/include/qi_subrule.hpp>
  19. #include <iostream>
  20. #include <string>
  21. namespace client
  22. {
  23. namespace qi = boost::spirit::qi;
  24. namespace repo = boost::spirit::repository;
  25. namespace ascii = boost::spirit::ascii;
  26. ///////////////////////////////////////////////////////////////////////////////
  27. // Our calculator grammar
  28. ///////////////////////////////////////////////////////////////////////////////
  29. template <typename Iterator>
  30. struct calculator : qi::grammar<Iterator, ascii::space_type>
  31. {
  32. calculator() : calculator::base_type(entry)
  33. {
  34. using qi::uint_;
  35. //[calc1_sr_def
  36. entry = (
  37. expression =
  38. term
  39. >> *( ('+' >> term)
  40. | ('-' >> term)
  41. )
  42. , term =
  43. factor
  44. >> *( ('*' >> factor)
  45. | ('/' >> factor)
  46. )
  47. , factor =
  48. uint_
  49. | '(' >> expression >> ')'
  50. | ('-' >> factor)
  51. | ('+' >> factor)
  52. );
  53. //]
  54. }
  55. qi::rule<Iterator, ascii::space_type> entry;
  56. repo::qi::subrule<0> expression;
  57. repo::qi::subrule<1> term;
  58. repo::qi::subrule<2> factor;
  59. };
  60. }
  61. ///////////////////////////////////////////////////////////////////////////////
  62. // Main program
  63. ///////////////////////////////////////////////////////////////////////////////
  64. int
  65. main()
  66. {
  67. std::cout << "/////////////////////////////////////////////////////////\n\n";
  68. std::cout << "Expression parser...\n\n";
  69. std::cout << "/////////////////////////////////////////////////////////\n\n";
  70. std::cout << "Type an expression...or [q or Q] to quit\n\n";
  71. using boost::spirit::ascii::space;
  72. typedef std::string::const_iterator iterator_type;
  73. typedef client::calculator<iterator_type> calculator;
  74. calculator calc; // Our grammar
  75. std::string str;
  76. while (std::getline(std::cin, str))
  77. {
  78. if (str.empty() || str[0] == 'q' || str[0] == 'Q')
  79. break;
  80. std::string::const_iterator iter = str.begin();
  81. std::string::const_iterator end = str.end();
  82. bool r = phrase_parse(iter, end, calc, space);
  83. if (r && iter == end)
  84. {
  85. std::cout << "-------------------------\n";
  86. std::cout << "Parsing succeeded\n";
  87. std::cout << "-------------------------\n";
  88. }
  89. else
  90. {
  91. std::string rest(iter, end);
  92. std::cout << "-------------------------\n";
  93. std::cout << "Parsing failed\n";
  94. std::cout << "stopped at: \": " << rest << "\"\n";
  95. std::cout << "-------------------------\n";
  96. }
  97. }
  98. std::cout << "Bye... :-) \n\n";
  99. return 0;
  100. }