]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/example/support/utree/sexpr_parser.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / spirit / example / support / utree / sexpr_parser.hpp
1 /*==============================================================================
2 Copyright (c) 2001-2011 Joel de Guzman
3 Copyright (c) 2010-2011 Bryce Lelbach
4
5 Distributed under the Boost Software License, Version 1.0. (See accompanying
6 file BOOST_LICENSE_1_0.rst or copy at http://www.boost.org/LICENSE_1_0.txt)
7 ==============================================================================*/
8
9 #if !defined(BOOST_SPIRIT_UTREE_EXAMPLE_SEXPR_PARSER_HPP)
10 #define BOOST_SPIRIT_UTREE_EXAMPLE_SEXPR_PARSER_HPP
11
12 #include "utf8_parser.hpp"
13 #include "error_handler.hpp"
14
15 namespace boost {
16 namespace spirit {
17 namespace traits {
18
19 template<>
20 struct transform_attribute<utree::nil_type, unused_type, qi::domain> {
21 typedef unused_type type;
22
23 static unused_type pre (utree::nil_type&) { return unused_type(); }
24 static void post (utree::nil_type&, unused_type) { }
25 static void fail (utree::nil_type&) { }
26 };
27
28 } // traits
29 } // spirit
30 } // boost
31
32 namespace sexpr
33 {
34
35 namespace qi = boost::spirit::qi;
36 namespace px = boost::phoenix;
37 namespace standard = boost::spirit::standard;
38
39 using boost::spirit::utree;
40 using boost::spirit::utf8_symbol_type;
41 using boost::spirit::utf8_string_type;
42 using boost::spirit::binary_string_type;
43
44 struct bool_input_policies
45 {
46 template <typename Iterator, typename Attribute>
47 static bool
48 parse_true(Iterator& first, Iterator const& last, Attribute& attr)
49 {
50 using boost::spirit::qi::detail::string_parse;
51 using boost::spirit::qi::bool_policies;
52 using boost::spirit::qi::unused;
53 using boost::spirit::traits::assign_to;
54 if (string_parse("#t", first, last, unused))
55 {
56 assign_to(true, attr); // result is true
57 return true;
58 }
59 return bool_policies<bool>::parse_true(first, last, attr);
60 }
61
62 template <typename Iterator, typename Attribute>
63 static bool
64 parse_false(Iterator& first, Iterator const& last, Attribute& attr)
65 {
66 using boost::spirit::qi::detail::string_parse;
67 using boost::spirit::qi::bool_policies;
68 using boost::spirit::qi::unused;
69 using boost::spirit::traits::assign_to;
70 if (string_parse("#f", first, last, unused))
71 {
72 assign_to(false, attr); // result is false
73 return true;
74 }
75 return bool_policies<bool>::parse_false(first, last, attr);
76 }
77 };
78
79 struct save_line_pos
80 {
81 template <typename, typename>
82 struct result
83 {
84 typedef void type;
85 };
86
87 template <typename Range>
88 void operator()(utree& ast, Range const& rng) const
89 {
90 using boost::spirit::get_line;
91 std::size_t n = get_line(rng.begin());
92 if (n != -1)
93 {
94 BOOST_ASSERT(n <= (std::numeric_limits<short>::max)());
95 ast.tag(n);
96 }
97 else
98 ast.tag(-1);
99 }
100 };
101
102 template <typename Iterator, typename F>
103 struct tagger : qi::grammar<Iterator, void(utree&, char)>
104 {
105 qi::rule<Iterator, void(utree&, char)>
106 start;
107
108 qi::rule<Iterator, void(utree&)>
109 epsilon;
110
111 px::function<F>
112 f;
113
114 tagger(F f_ = F()) : tagger::base_type(start), f(f_)
115 {
116 using qi::omit;
117 using qi::raw;
118 using qi::eps;
119 using qi::lit;
120 using qi::_1;
121 using qi::_r1;
122 using qi::_r2;
123
124 start = omit[raw[lit(_r2)] [f(_r1, _1)]];
125
126 epsilon = omit[raw[eps] [f(_r1, _1)]];
127 }
128 };
129
130 template <typename Iterator>
131 struct whitespace : qi::grammar<Iterator> {
132 qi::rule<Iterator>
133 start;
134
135 whitespace() : whitespace::base_type(start)
136 {
137 using standard::space;
138 using standard::char_;
139 using qi::eol;
140
141 start = space | (';' >> *(char_ - eol) >> eol);
142 }
143 };
144
145 } // sexpr
146
147 //[utree_sexpr_parser
148 namespace sexpr
149 {
150
151 template <typename Iterator, typename ErrorHandler = error_handler<Iterator> >
152 struct parser : qi::grammar<Iterator, utree(), whitespace<Iterator> >
153 {
154 qi::rule<Iterator, utree(), whitespace<Iterator> >
155 start, element, list;
156
157 qi::rule<Iterator, utree()>
158 atom;
159
160 qi::rule<Iterator, int()>
161 integer;
162
163 qi::rule<Iterator, utf8_symbol_type()>
164 symbol;
165
166 qi::rule<Iterator, utree::nil_type()>
167 nil_;
168
169 qi::rule<Iterator, binary_string_type()>
170 binary;
171
172 utf8::parser<Iterator>
173 string;
174
175 px::function<ErrorHandler> const
176 error;
177
178 tagger<Iterator, save_line_pos>
179 pos;
180
181 parser(std::string const& source_file = "<string>"):
182 parser::base_type(start), error(ErrorHandler(source_file))
183 {
184 using standard::char_;
185 using qi::unused_type;
186 using qi::lexeme;
187 using qi::hex;
188 using qi::oct;
189 using qi::no_case;
190 using qi::real_parser;
191 using qi::strict_real_policies;
192 using qi::uint_parser;
193 using qi::bool_parser;
194 using qi::on_error;
195 using qi::fail;
196 using qi::int_;
197 using qi::lit;
198 using qi::_val;
199 using qi::_1;
200 using qi::_2;
201 using qi::_3;
202 using qi::_4;
203
204 real_parser<double, strict_real_policies<double> > strict_double;
205 uint_parser<unsigned char, 16, 2, 2> hex2;
206 bool_parser<bool, sexpr::bool_input_policies> boolean;
207
208 start = element.alias();
209
210 element = atom | list;
211
212 list = pos(_val, '(') > *element > ')';
213
214 atom = nil_
215 | strict_double
216 | integer
217 | boolean
218 | string
219 | symbol
220 | binary;
221
222 nil_ = qi::attr_cast(lit("nil"));
223
224 integer = lexeme[ no_case["#x"] > hex]
225 | lexeme[ no_case["#o"] >> oct]
226 | lexeme[-no_case["#d"] >> int_];
227
228 std::string exclude = std::string(" ();\"\x01-\x1f\x7f") + '\0';
229 symbol = lexeme[+(~char_(exclude))];
230
231 binary = lexeme['#' > *hex2 > '#'];
232
233 start.name("sexpr");
234 element.name("element");
235 list.name("list");
236 atom.name("atom");
237 nil_.name("nil");
238 integer.name("integer");
239 symbol.name("symbol");
240 binary.name("binary");
241
242 on_error<fail>(start, error(_1, _2, _3, _4));
243 }
244 };
245
246 } // sexpr
247 //]
248
249 #endif // BOOST_SPIRIT_UTREE_EXAMPLE_SEXPR_PARSER_HPP
250