• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
preprocessorclient::preprocessor38         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>
parse(Iterator & first,Iterator end,Skipper const & 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 
main()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 
99