complex_number.cpp 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /*=============================================================================
  2. Copyright (c) 2002-2015 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. // A complex number micro parser.
  9. //
  10. // [ JDG May 10, 2002 ] spirit1
  11. // [ JDG May 9, 2007 ] spirit2
  12. // [ JDG May 12, 2015 ] spirit X3
  13. //
  14. ///////////////////////////////////////////////////////////////////////////////
  15. #include <boost/config/warning_disable.hpp>
  16. #include <boost/spirit/home/x3.hpp>
  17. #include <iostream>
  18. #include <string>
  19. #include <complex>
  20. ///////////////////////////////////////////////////////////////////////////////
  21. // Our complex number parser/compiler
  22. ///////////////////////////////////////////////////////////////////////////////
  23. namespace client
  24. {
  25. template <typename Iterator>
  26. bool parse_complex(Iterator first, Iterator last, std::complex<double>& c)
  27. {
  28. using boost::spirit::x3::double_;
  29. using boost::spirit::x3::_attr;
  30. using boost::spirit::x3::phrase_parse;
  31. using boost::spirit::x3::ascii::space;
  32. double rN = 0.0;
  33. double iN = 0.0;
  34. auto fr = [&](auto& ctx){ rN = _attr(ctx); };
  35. auto fi = [&](auto& ctx){ iN = _attr(ctx); };
  36. bool r = phrase_parse(first, last,
  37. // Begin grammar
  38. (
  39. '(' >> double_[fr]
  40. >> -(',' >> double_[fi]) >> ')'
  41. | double_[fr]
  42. ),
  43. // End grammar
  44. space);
  45. if (!r || first != last) // fail if we did not get a full match
  46. return false;
  47. c = std::complex<double>(rN, iN);
  48. return r;
  49. }
  50. }
  51. ////////////////////////////////////////////////////////////////////////////
  52. // Main program
  53. ////////////////////////////////////////////////////////////////////////////
  54. int
  55. main()
  56. {
  57. std::cout << "/////////////////////////////////////////////////////////\n\n";
  58. std::cout << "\t\tA complex number micro parser for Spirit...\n\n";
  59. std::cout << "/////////////////////////////////////////////////////////\n\n";
  60. std::cout << "Give me a complex number of the form r or (r) or (r,i) \n";
  61. std::cout << "Type [q or Q] to quit\n\n";
  62. std::string str;
  63. while (getline(std::cin, str))
  64. {
  65. if (str.empty() || str[0] == 'q' || str[0] == 'Q')
  66. break;
  67. std::complex<double> c;
  68. if (client::parse_complex(str.begin(), str.end(), c))
  69. {
  70. std::cout << "-------------------------\n";
  71. std::cout << "Parsing succeeded\n";
  72. std::cout << "got: " << c << std::endl;
  73. std::cout << "\n-------------------------\n";
  74. }
  75. else
  76. {
  77. std::cout << "-------------------------\n";
  78. std::cout << "Parsing failed\n";
  79. std::cout << "-------------------------\n";
  80. }
  81. }
  82. std::cout << "Bye... :-) \n\n";
  83. return 0;
  84. }