advance.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. // Copyright (c) 2011 Aaron Graham
  2. //
  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. // The purpose of this example is to demonstrate the use of the advance parser.
  6. //[qi_advance_includes
  7. #include <boost/spirit/include/qi.hpp>
  8. #include <boost/spirit/include/phoenix_operator.hpp>
  9. #include <boost/spirit/repository/include/qi_advance.hpp>
  10. //]
  11. #include <list>
  12. #include <string>
  13. //[qi_advance_namespaces
  14. namespace qi = boost::spirit::qi;
  15. using boost::spirit::repository::qi::advance;
  16. //]
  17. namespace client
  18. {
  19. //[qi_advance_grammar
  20. template <typename Iterator>
  21. struct advance_grammar : qi::grammar<Iterator, qi::locals<int> >
  22. {
  23. advance_grammar() : advance_grammar::base_type(start)
  24. {
  25. using qi::byte_;
  26. using qi::eoi;
  27. using namespace qi::labels;
  28. start
  29. = byte_ [_a = _1]
  30. >> advance(_a)
  31. >> "boost"
  32. >> byte_ [_a = _1]
  33. >> (advance(_a) | "qi") // note alternative when advance fails
  34. >> eoi
  35. ;
  36. }
  37. qi::rule<Iterator, qi::locals<int> > start;
  38. };
  39. //]
  40. }
  41. int main()
  42. {
  43. // This parser is tested with both random access iterators (std::string)
  44. // and bidirectional iterators (std::list).
  45. char const* result;
  46. //[qi_advance_example1
  47. unsigned char const alt1[] =
  48. {
  49. 5, // number of bytes to advance
  50. 1, 2, 3, 4, 5, // data to advance through
  51. 'b', 'o', 'o', 's', 't', // word to parse
  52. 2, // number of bytes to advance
  53. 11, 12 // more data to advance through
  54. // eoi
  55. };
  56. std::string const alt1_string(alt1, alt1 + sizeof alt1);
  57. std::list<unsigned char> const alt1_list(alt1, alt1 + sizeof alt1);
  58. result =
  59. qi::parse(alt1_string.begin(), alt1_string.end()
  60. , client::advance_grammar<std::string::const_iterator>())
  61. ? "succeeded" : "failed";
  62. std::cout << "Parsing alt1 using random access iterator " << result << std::endl;
  63. result =
  64. qi::parse(alt1_list.begin(), alt1_list.end()
  65. , client::advance_grammar<std::list<unsigned char>::const_iterator>())
  66. ? "succeeded" : "failed";
  67. std::cout << "Parsing alt1 using bidirectional iterator " << result << std::endl;
  68. //]
  69. //[qi_advance_example2
  70. unsigned char const alt2[] =
  71. {
  72. 2, // number of bytes to advance
  73. 1, 2, // data to advance through
  74. 'b', 'o', 'o', 's', 't', // word to parse
  75. 4, // number of bytes to advance
  76. 'q', 'i' // alternative (advance won't work)
  77. // eoi
  78. };
  79. std::string const alt2_string(alt2, alt2 + sizeof alt2);
  80. std::list<unsigned char> const alt2_list(alt2, alt2 + sizeof alt2);
  81. result =
  82. qi::parse(alt2_string.begin(), alt2_string.end()
  83. , client::advance_grammar<std::string::const_iterator>())
  84. ? "succeeded" : "failed";
  85. std::cout << "Parsing alt2 using random access iterator " << result << std::endl;
  86. result =
  87. qi::parse(alt2_list.begin(), alt2_list.end()
  88. , client::advance_grammar<std::list<unsigned char>::const_iterator>())
  89. ? "succeeded" : "failed";
  90. std::cout << "Parsing alt2 using bidirectional iterator " << result << std::endl;
  91. //]
  92. return 0;
  93. }