]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/example/x3/rexpr/rexpr_min/rexpr.cpp
1 /*=============================================================================
2 Copyright (c) 2001-2015 Joel de Guzman
4 Distributed under the Boost Software License, Version 1.0. (See accompanying
5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 =============================================================================*/
7 ///////////////////////////////////////////////////////////////////////////////
9 // A simple parser for X3 intended as a minimal starting point.
10 // 'rexpr' is a parser for a language resembling a minimal subset
11 // of json, but limited to a dictionary (composed of key=value pairs)
12 // where the value can itself be a string or a recursive dictionary.
25 ///////////////////////////////////////////////////////////////////////////////
27 #include <boost/spirit/home/x3.hpp>
28 #include <boost/spirit/home/x3/support/ast/variant.hpp>
29 #include <boost/fusion/include/adapt_struct.hpp>
30 #include <boost/fusion/include/std_pair.hpp>
31 #include <boost/fusion/include/io.hpp>
38 ///////////////////////////////////////////////////////////////////////////////
40 ///////////////////////////////////////////////////////////////////////////////
41 namespace client
{ namespace ast
43 namespace fusion
= boost::fusion
;
44 namespace x3
= boost::spirit::x3
;
48 struct rexpr_value
: x3::variant
<
50 , x3::forward_ast
<rexpr
>
53 using base_type::base_type
;
54 using base_type::operator=;
57 typedef std::map
<std::string
, rexpr_value
> rexpr_map
;
58 typedef std::pair
<std::string
, rexpr_value
> rexpr_key_value
;
66 // We need to tell fusion about our rexpr struct
67 // to make it a first-class fusion citizen
68 BOOST_FUSION_ADAPT_STRUCT(client::ast::rexpr
,
72 ///////////////////////////////////////////////////////////////////////////////
74 ///////////////////////////////////////////////////////////////////////////////
75 namespace client
{ namespace ast
77 ///////////////////////////////////////////////////////////////////////////
78 // Print out the rexpr tree
79 ///////////////////////////////////////////////////////////////////////////
80 int const tabsize
= 4;
84 typedef void result_type
;
86 rexpr_printer(int indent
= 0)
89 void operator()(rexpr
const& ast
) const
91 std::cout
<< '{' << std::endl
;
92 for (auto const& entry
: ast
.entries
)
95 std::cout
<< '"' << entry
.first
<< "\" = ";
96 boost::apply_visitor(rexpr_printer(indent
+tabsize
), entry
.second
);
99 std::cout
<< '}' << std::endl
;
102 void operator()(std::string
const& text
) const
104 std::cout
<< '"' << text
<< '"' << std::endl
;
107 void tab(int spaces
) const
109 for (int i
= 0; i
< spaces
; ++i
)
117 ///////////////////////////////////////////////////////////////////////////////
119 ///////////////////////////////////////////////////////////////////////////////
120 namespace client
{ namespace parser
122 namespace x3
= boost::spirit::x3
;
123 namespace ascii
= boost::spirit::x3::ascii
;
131 x3::rule
<class rexpr_value
, ast::rexpr_value
>
132 rexpr_value
= "rexpr_value";
134 x3::rule
<class rexpr
, ast::rexpr
>
137 x3::rule
<class rexpr_key_value
, ast::rexpr_key_value
>
138 rexpr_key_value
= "rexpr_key_value";
140 auto const quoted_string
=
141 lexeme
['"' >> *(char_
- '"') >> '"'];
143 auto const rexpr_value_def
=
144 quoted_string
| rexpr
;
146 auto const rexpr_key_value_def
=
147 quoted_string
>> '=' >> rexpr_value
;
149 auto const rexpr_def
=
150 '{' >> *rexpr_key_value
>> '}';
152 BOOST_SPIRIT_DEFINE(rexpr_value
, rexpr
, rexpr_key_value
);
155 ///////////////////////////////////////////////////////////////////////////////
157 ///////////////////////////////////////////////////////////////////////////////
158 int main(int argc
, char **argv
)
160 char const* filename
;
167 std::cerr
<< "Error: No input file provided." << std::endl
;
171 std::ifstream
in(filename
, std::ios_base::in
);
175 std::cerr
<< "Error: Could not open input file: "
176 << filename
<< std::endl
;
180 std::string storage
; // We will read the contents here.
181 in
.unsetf(std::ios::skipws
); // No white space skipping!
183 std::istream_iterator
<char>(in
),
184 std::istream_iterator
<char>(),
185 std::back_inserter(storage
));
187 using client::parser::rexpr
; // Our grammar
188 client::ast::rexpr ast
; // Our tree
190 using boost::spirit::x3::ascii::space
;
191 std::string::const_iterator iter
= storage
.begin();
192 std::string::const_iterator end
= storage
.end();
193 bool r
= phrase_parse(iter
, end
, rexpr
, space
, ast
);
195 if (r
&& iter
== end
)
197 std::cout
<< "-------------------------\n";
198 std::cout
<< "Parsing succeeded\n";
199 std::cout
<< "-------------------------\n";
200 client::ast::rexpr_printer printer
;
206 std::string::const_iterator some
= iter
+30;
207 std::string
context(iter
, (some
>end
)?end
:some
);
208 std::cout
<< "-------------------------\n";
209 std::cout
<< "Parsing failed\n";
210 std::cout
<< "stopped at: \": " << context
<< "...\"\n";
211 std::cout
<< "-------------------------\n";