switch_problem.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. /*=============================================================================
  2. Copyright (c) 2004 Angus Leeming
  3. http://spirit.sourceforge.net/
  4. Use, modification and distribution is subject to the Boost Software
  5. License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  6. http://www.boost.org/LICENSE_1_0.txt)
  7. =============================================================================*/
  8. ///////////////////////////////////////////////////////////////////////////////
  9. //
  10. // The switch_p parser was broken sometime during the boost 1.32 development
  11. // cycle. This little program tests it, the for_p parser and the limit_d
  12. // directive.
  13. //
  14. ///////////////////////////////////////////////////////////////////////////////
  15. #include <boost/spirit/include/classic_core.hpp>
  16. #include <boost/spirit/include/classic_for.hpp>
  17. #include <boost/spirit/include/classic_switch.hpp>
  18. #include <boost/spirit/include/classic_position_iterator.hpp>
  19. #include <boost/spirit/include/classic_confix.hpp>
  20. #include <boost/spirit/include/phoenix1.hpp>
  21. #include <iostream>
  22. #include <string>
  23. namespace spirit = BOOST_SPIRIT_CLASSIC_NS;
  24. typedef unsigned int uint;
  25. struct switch_grammar : public spirit::grammar<switch_grammar> {
  26. template <typename ScannerT>
  27. struct definition {
  28. definition(switch_grammar const & self);
  29. typedef spirit::rule<ScannerT> rule_t;
  30. rule_t const & start() const { return expression; }
  31. private:
  32. rule_t expression;
  33. uint index;
  34. uint nnodes;
  35. };
  36. };
  37. template <typename ScannerT>
  38. switch_grammar::definition<ScannerT>::definition(switch_grammar const & /*self*/)
  39. {
  40. using boost::cref;
  41. using phoenix::arg1;
  42. using phoenix::var;
  43. using spirit::case_p;
  44. using spirit::for_p;
  45. using spirit::limit_d;
  46. using spirit::str_p;
  47. using spirit::switch_p;
  48. using spirit::uint_p;
  49. expression =
  50. str_p("NNODES") >>
  51. uint_p[var(nnodes) = arg1] >>
  52. for_p(var(index) = 1,
  53. var(index) <= var(nnodes),
  54. var(index)++)
  55. [
  56. limit_d(cref(index), cref(index))[uint_p] >>
  57. switch_p[
  58. case_p<'s'>(uint_p),
  59. case_p<'d'>(uint_p),
  60. case_p<'n'>(uint_p)
  61. ]
  62. ];
  63. }
  64. int main()
  65. {
  66. std::string const data("NNODES 3\n"
  67. "1 s 1\n"
  68. "2 d 2\n"
  69. "3 n 3"); // JDG 10-18-2005 removed trailing \n to
  70. // avoid post skip problems
  71. typedef spirit::position_iterator<std::string::const_iterator>
  72. iterator_t;
  73. spirit::parse_info<iterator_t> const info =
  74. parse(iterator_t(data.begin(), data.end(), "switch test"),
  75. iterator_t(),
  76. switch_grammar(),
  77. spirit::space_p);
  78. if (!info.full) {
  79. spirit::file_position const fp = info.stop.get_position();
  80. std::cerr << "Parsing failed at line " << fp.line
  81. << ", column " << fp.column << ".\n";
  82. }
  83. return info.full ? 0 : 1;
  84. }