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