calc1.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /*=============================================================================
  2. Copyright (c) 2001-2011 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 ] spirit1
  12. // [ JDG March 4, 2007 ] spirit2
  13. // [ JDG February 21, 2011 ] spirit2.5
  14. //
  15. ///////////////////////////////////////////////////////////////////////////////
  16. // Spirit v2.5 allows you to suppress automatic generation
  17. // of predefined terminals to speed up complation. With
  18. // BOOST_SPIRIT_NO_PREDEFINED_TERMINALS defined, you are
  19. // responsible in creating instances of the terminals that
  20. // you need (e.g. see qi::uint_type uint_ below).
  21. #define BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
  22. #include <boost/config/warning_disable.hpp>
  23. #include <boost/spirit/include/qi.hpp>
  24. #include <iostream>
  25. #include <string>
  26. namespace client
  27. {
  28. namespace qi = boost::spirit::qi;
  29. namespace ascii = boost::spirit::ascii;
  30. ///////////////////////////////////////////////////////////////////////////////
  31. // Our calculator grammar
  32. ///////////////////////////////////////////////////////////////////////////////
  33. template <typename Iterator>
  34. struct calculator : qi::grammar<Iterator, ascii::space_type>
  35. {
  36. calculator() : calculator::base_type(expression)
  37. {
  38. qi::uint_type uint_;
  39. expression =
  40. term
  41. >> *( ('+' >> term)
  42. | ('-' >> term)
  43. )
  44. ;
  45. term =
  46. factor
  47. >> *( ('*' >> factor)
  48. | ('/' >> factor)
  49. )
  50. ;
  51. factor =
  52. uint_
  53. | '(' >> expression >> ')'
  54. | ('-' >> factor)
  55. | ('+' >> factor)
  56. ;
  57. }
  58. qi::rule<Iterator, ascii::space_type> expression, term, 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. typedef std::string::const_iterator iterator_type;
  72. typedef client::calculator<iterator_type> calculator;
  73. boost::spirit::ascii::space_type space; // Our skipper
  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. }