]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/repository/example/qi/flush_multi_pass.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / spirit / repository / example / qi / flush_multi_pass.cpp
1 // Copyright (c) 2001-2010 Hartmut Kaiser
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 a simple use case for the
7 // flush_multi_pass parser.
8
9 #include <iostream>
10 #include <fstream>
11 #include <string>
12
13 //[qi_flush_multi_pass_includes
14 #include <boost/spirit/include/qi.hpp>
15 #include <boost/spirit/repository/include/qi_flush_multi_pass.hpp>
16 //]
17
18 //[qi_flush_multi_pass_namespace
19 namespace spirit = boost::spirit;
20 using boost::spirit::repository::flush_multi_pass;
21 //]
22
23 namespace client
24 {
25 //[qi_flush_multi_pass_clear_buffer
26 template <typename Iterator, typename Skipper>
27 struct preprocessor : spirit::qi::grammar<Iterator, Skipper>
28 {
29 // This is a simplified preprocessor grammar recognizing
30 //
31 // #define MACRONAME something
32 // #undef MACRONAME
33 //
34 // Its sole purpose is to show an example how to use the
35 // flush_multi_pass parser. At the end of each line no backtracking can
36 // occur anymore so that it's safe to clear all internal buffers in the
37 // multi_pass.
38 preprocessor() : preprocessor::base_type(file)
39 {
40 using spirit::ascii::char_;
41 using spirit::qi::eol;
42 using spirit::qi::lit;
43
44 file =
45 *line
46 ;
47
48 line = ( command | *(char_ - eol) )
49 >> eol
50 >> flush_multi_pass
51 ;
52
53 command =
54 "#define" >> *lit(' ') >> *(char_ - ' ') >> *lit(' ') >> *(char_ - eol)
55 | "#undef" >> *lit(' ') >> *(char_ - eol)
56 ;
57 }
58
59 spirit::qi::rule<Iterator, Skipper> file, line, command;
60 };
61 //]
62 }
63
64 template <typename Iterator, typename Skipper>
65 bool parse(Iterator& first, Iterator end, Skipper const& skipper)
66 {
67 client::preprocessor<Iterator, Skipper> g;
68 return boost::spirit::qi::phrase_parse(first, end, g, skipper);
69 }
70
71 int main()
72 {
73 namespace spirit = boost::spirit;
74 using spirit::ascii::char_;
75 using spirit::qi::eol;
76
77 std::ifstream in("flush_multi_pass.txt"); // we get our input from this file
78 if (!in.is_open()) {
79 std::cout << "Could not open input file: 'flush_multi_pass.txt'" << std::endl;
80 return -1;
81 }
82
83 typedef std::istreambuf_iterator<char> base_iterator_type;
84 spirit::multi_pass<base_iterator_type> first =
85 spirit::make_default_multi_pass(base_iterator_type(in));
86 spirit::multi_pass<base_iterator_type> end =
87 spirit::make_default_multi_pass(base_iterator_type());
88
89 bool result = parse(first, end, '#' >> *(char_ - eol) >> eol);
90 if (!result) {
91 std::cout << "Failed parsing input file!" << std::endl;
92 return -2;
93 }
94
95 std::cout << "Successfully parsed input file!" << std::endl;
96 return 0;
97 }
98