complex.qbk 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. [/==============================================================================
  2. Copyright (C) 2001-2015 Joel de Guzman
  3. Copyright (C) 2001-2011 Hartmut Kaiser
  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. [section Complex - Our first complex parser]
  8. Well, not really a complex parser, but a parser that parses complex numbers.
  9. Here's a simple parser expression for complex numbers:
  10. '(' >> double_ >> -(',' >> double_) >> ')'
  11. | double_
  12. What's new? Well, we have:
  13. # Alternates: e.g. `a | b`. Try `a` first. If it succeeds, good. If not, try the
  14. next alternative, `b`.
  15. # Optionals: e.g. -p. Match the parser p zero or one time.
  16. The complex parser presented above reads as:
  17. * One or two real numbers in parentheses, separated by comma (the second number is optional)
  18. * *OR* a single real number.
  19. This parser can parse complex numbers of the form:
  20. (123.45, 987.65)
  21. (123.45)
  22. 123.45
  23. Here goes, this time with actions:
  24. namespace client
  25. {
  26. template <typename Iterator>
  27. bool parse_complex(Iterator first, Iterator last, std::complex<double>& c)
  28. {
  29. using boost::spirit::x3::double_;
  30. using boost::spirit::x3::_attr;
  31. using boost::spirit::x3::phrase_parse;
  32. using boost::spirit::x3::ascii::space;
  33. double rN = 0.0;
  34. double iN = 0.0;
  35. auto fr = [&](auto& ctx){ rN = _attr(ctx); };
  36. auto fi = [&](auto& ctx){ iN = _attr(ctx); };
  37. bool r = phrase_parse(first, last,
  38. // Begin grammar
  39. (
  40. '(' >> double_[fr]
  41. >> -(',' >> double_[fi]) >> ')'
  42. | double_[fr]
  43. ),
  44. // End grammar
  45. space);
  46. if (!r || first != last) // fail if we did not get a full match
  47. return false;
  48. c = std::complex<double>(rN, iN);
  49. return r;
  50. }
  51. }
  52. The full cpp file for this example can be found here:
  53. [@../../../example/x3/complex_number.cpp complex_number.cpp]
  54. The `double_` parser attaches this action:
  55. [&](auto& ctx){ n = _attr(ctx); }
  56. This assigns the parsed result (actually, the attribute of `double_`) to n.
  57. [endsect]