]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | #ifndef BOOST_METAPARSE_V1_GRAMMAR_HPP |
2 | #define BOOST_METAPARSE_V1_GRAMMAR_HPP | |
3 | ||
4 | // Copyright Abel Sinkovics (abel@sinkovics.hu) 2012. | |
5 | // Distributed under the Boost Software License, Version 1.0. | |
6 | // (See accompanying file LICENSE_1_0.txt or copy at | |
7 | // http://www.boost.org/LICENSE_1_0.txt) | |
8 | ||
9 | #include <boost/metaparse/v1/repeated.hpp> | |
10 | #include <boost/metaparse/v1/repeated1.hpp> | |
11 | #include <boost/metaparse/v1/sequence.hpp> | |
12 | #include <boost/metaparse/v1/one_of.hpp> | |
13 | #include <boost/metaparse/v1/transform.hpp> | |
14 | #include <boost/metaparse/v1/lit.hpp> | |
15 | #include <boost/metaparse/v1/lit_c.hpp> | |
16 | #include <boost/metaparse/v1/token.hpp> | |
17 | #include <boost/metaparse/v1/keyword.hpp> | |
18 | #include <boost/metaparse/v1/middle_of.hpp> | |
19 | #include <boost/metaparse/v1/last_of.hpp> | |
20 | #include <boost/metaparse/v1/always.hpp> | |
21 | #include <boost/metaparse/v1/one_char_except_c.hpp> | |
22 | #include <boost/metaparse/v1/foldr1.hpp> | |
23 | #include <boost/metaparse/v1/foldl_start_with_parser.hpp> | |
24 | #include <boost/metaparse/v1/alphanum.hpp> | |
25 | #include <boost/metaparse/v1/build_parser.hpp> | |
26 | #include <boost/metaparse/v1/entire_input.hpp> | |
27 | #include <boost/metaparse/v1/string.hpp> | |
28 | #include <boost/metaparse/v1/impl/front_inserter.hpp> | |
29 | ||
30 | #include <boost/mpl/at.hpp> | |
31 | #include <boost/mpl/map.hpp> | |
32 | #include <boost/mpl/eval_if.hpp> | |
33 | #include <boost/mpl/has_key.hpp> | |
34 | #include <boost/mpl/lambda.hpp> | |
35 | #include <boost/mpl/front.hpp> | |
36 | #include <boost/mpl/back.hpp> | |
37 | #include <boost/mpl/pair.hpp> | |
38 | #include <boost/mpl/insert.hpp> | |
39 | ||
40 | /* | |
41 | * The grammar | |
42 | * | |
43 | * rule_definition ::= name_token define_token expression | |
44 | * expression ::= seq_expression (or_token seq_expression)* | |
45 | * seq_expression ::= repeated_expression+ | |
46 | * repeated_expression ::= name_expression (repeated_token | repeated1_token)* | |
47 | * name_expression ::= char_token | name_token | bracket_expression | |
48 | * bracket_expression ::= open_bracket_token expression close_bracket_token | |
49 | */ | |
50 | ||
51 | namespace boost | |
52 | { | |
53 | namespace metaparse | |
54 | { | |
55 | namespace v1 | |
56 | { | |
57 | namespace grammar_util | |
58 | { | |
59 | template <char Op, class FState> | |
60 | struct repeated_apply_impl | |
61 | { | |
62 | typedef repeated_apply_impl type; | |
63 | ||
64 | template <class G> | |
65 | struct apply : | |
66 | repeated<typename FState::template apply<G>::type> | |
67 | {}; | |
68 | }; | |
69 | ||
70 | template <class FState> | |
71 | struct repeated_apply_impl<'+', FState> | |
72 | { | |
73 | typedef repeated_apply_impl type; | |
74 | ||
75 | template <class G> | |
76 | struct apply : | |
77 | repeated1<typename FState::template apply<G>::type> | |
78 | {}; | |
79 | }; | |
80 | ||
81 | struct build_repeated | |
82 | { | |
83 | typedef build_repeated type; | |
84 | ||
85 | template <class FState, class T> | |
86 | struct apply : repeated_apply_impl<T::type::value, FState> {}; | |
87 | }; | |
88 | ||
89 | struct build_sequence | |
90 | { | |
91 | typedef build_sequence type; | |
92 | ||
93 | template <class FState, class FP> | |
94 | struct apply_impl | |
95 | { | |
96 | typedef apply_impl type; | |
97 | ||
98 | template <class G> | |
99 | struct apply : | |
100 | sequence< | |
101 | typename FState::template apply<G>::type, | |
102 | typename FP::template apply<G>::type | |
103 | > | |
104 | {}; | |
105 | }; | |
106 | ||
107 | template <class FState, class FP> | |
108 | struct apply : apply_impl<FState, FP> {}; | |
109 | }; | |
110 | ||
111 | struct build_selection | |
112 | { | |
113 | typedef build_selection type; | |
114 | ||
115 | template <class FState, class FP> | |
116 | struct apply_impl | |
117 | { | |
118 | typedef apply_impl type; | |
119 | ||
120 | template <class G> | |
121 | struct apply : | |
122 | one_of< | |
123 | typename FState::template apply<G>::type, | |
124 | typename FP::template apply<G>::type | |
125 | > | |
126 | {}; | |
127 | }; | |
128 | ||
129 | template <class FState, class FP> | |
130 | struct apply : apply_impl<FState, FP> {}; | |
131 | }; | |
132 | ||
133 | template <class G, class Name> | |
134 | struct get_parser | |
135 | { | |
136 | typedef | |
137 | typename boost::mpl::at<typename G::rules, Name>::type | |
138 | ::template apply<G> | |
139 | p; | |
140 | ||
141 | template <class Actions> | |
142 | struct impl : transform<typename p::type, typename Actions::type> {}; | |
143 | ||
144 | typedef | |
145 | typename boost::mpl::eval_if< | |
146 | typename boost::mpl::has_key<typename G::actions, Name>::type, | |
147 | impl<boost::mpl::at<typename G::actions, Name> >, | |
148 | p | |
149 | >::type | |
150 | type; | |
151 | }; | |
152 | ||
153 | struct build_name | |
154 | { | |
155 | typedef build_name type; | |
156 | ||
157 | template <class Name> | |
158 | struct apply_impl | |
159 | { | |
160 | typedef apply_impl type; | |
161 | ||
162 | template <class G> | |
163 | struct apply : get_parser<G, Name> {}; | |
164 | }; | |
165 | ||
166 | template <class Name> | |
167 | struct apply : apply_impl<Name> {}; | |
168 | }; | |
169 | ||
170 | struct build_char | |
171 | { | |
172 | typedef build_char type; | |
173 | ||
174 | template <class C> | |
175 | struct apply_impl | |
176 | { | |
177 | typedef apply_impl type; | |
178 | ||
179 | template <class G> | |
180 | struct apply : lit<C> {}; | |
181 | }; | |
182 | ||
183 | template <class C> | |
184 | struct apply : apply_impl<C> {}; | |
185 | }; | |
186 | ||
187 | typedef token<lit_c<'*'> > repeated_token; | |
188 | typedef token<lit_c<'+'> > repeated1_token; | |
189 | typedef token<lit_c<'|'> > or_token; | |
190 | typedef token<lit_c<'('> > open_bracket_token; | |
191 | typedef token<lit_c<')'> > close_bracket_token; | |
192 | typedef token<keyword<string<':',':','='> > > define_token; | |
193 | ||
194 | typedef | |
195 | middle_of< | |
196 | lit_c<'\''>, | |
197 | one_of< | |
198 | last_of< | |
199 | lit_c<'\\'>, | |
200 | one_of< | |
201 | always<lit_c<'n'>, boost::mpl::char_<'\n'> >, | |
202 | always<lit_c<'r'>, boost::mpl::char_<'\r'> >, | |
203 | always<lit_c<'t'>, boost::mpl::char_<'\t'> >, | |
204 | lit_c<'\\'>, | |
205 | lit_c<'\''> | |
206 | > | |
207 | >, | |
208 | one_char_except_c<'\''> | |
209 | >, | |
210 | token<lit_c<'\''> > | |
211 | > | |
212 | char_token; | |
213 | ||
214 | typedef | |
215 | token< | |
216 | foldr1< | |
217 | one_of<alphanum, lit_c<'_'> >, | |
218 | string<>, | |
219 | impl::front_inserter | |
220 | > | |
221 | > | |
222 | name_token; | |
223 | ||
224 | struct expression; | |
225 | ||
226 | typedef | |
227 | middle_of<open_bracket_token, expression, close_bracket_token> | |
228 | bracket_expression; | |
229 | ||
230 | typedef | |
231 | one_of< | |
232 | transform<char_token, build_char>, | |
233 | transform<name_token, build_name>, | |
234 | bracket_expression | |
235 | > | |
236 | name_expression; | |
237 | ||
238 | typedef | |
239 | foldl_start_with_parser< | |
240 | one_of<repeated_token, repeated1_token>, | |
241 | name_expression, | |
242 | build_repeated | |
243 | > | |
244 | repeated_expression; | |
245 | ||
246 | typedef | |
247 | foldl_start_with_parser< | |
248 | repeated_expression, | |
249 | repeated_expression, | |
250 | build_sequence | |
251 | > | |
252 | seq_expression; | |
253 | ||
254 | struct expression : | |
255 | foldl_start_with_parser< | |
256 | last_of<or_token, seq_expression>, | |
257 | seq_expression, | |
258 | build_selection | |
259 | > | |
260 | {}; | |
261 | ||
262 | typedef sequence<name_token, define_token, expression> rule_definition; | |
263 | ||
264 | typedef build_parser<entire_input<rule_definition> > parser_parser; | |
265 | ||
266 | template <class P> | |
267 | struct build_native_parser | |
268 | { | |
269 | typedef build_native_parser type; | |
270 | ||
271 | template <class G> | |
272 | struct apply | |
273 | { | |
274 | typedef P type; | |
275 | }; | |
276 | }; | |
277 | ||
278 | template <class S> | |
279 | struct build_parsed_parser | |
280 | { | |
281 | typedef typename parser_parser::apply<S>::type p; | |
282 | typedef typename boost::mpl::front<p>::type name; | |
283 | typedef typename boost::mpl::back<p>::type exp; | |
284 | ||
285 | struct the_parser | |
286 | { | |
287 | typedef the_parser type; | |
288 | ||
289 | template <class G> | |
290 | struct apply : exp::template apply<G> {}; | |
291 | }; | |
292 | ||
293 | typedef boost::mpl::pair<name, the_parser> type; | |
294 | }; | |
295 | ||
296 | typedef build_parser<name_token> name_parser; | |
297 | ||
298 | template <class S> | |
299 | struct rebuild : name_parser::template apply<S> {}; | |
300 | ||
301 | struct no_action; | |
302 | ||
303 | template <class G, class P, class F> | |
304 | struct add_rule; | |
305 | ||
306 | template <class G, class Name, class P> | |
307 | struct add_import; | |
308 | ||
309 | template <class Start, class Rules, class Actions> | |
310 | struct grammar_builder | |
311 | { | |
312 | typedef grammar_builder type; | |
313 | typedef Rules rules; | |
314 | typedef Actions actions; | |
315 | ||
316 | // Make it a parser | |
317 | template <class S, class Pos> | |
318 | struct apply : | |
319 | get_parser< | |
320 | grammar_builder, | |
321 | typename rebuild<Start>::type | |
322 | >::type::template apply<S, Pos> | |
323 | {}; | |
324 | ||
325 | template <class Name, class P> | |
326 | struct import : | |
327 | add_import<grammar_builder, typename rebuild<Name>::type, P> | |
328 | {}; | |
329 | ||
330 | template <class Def, class Action = no_action> | |
331 | struct rule : | |
332 | add_rule<grammar_builder, build_parsed_parser<Def>, Action> | |
333 | {}; | |
334 | }; | |
335 | ||
336 | template <class Start, class Rules, class Actions, class P> | |
337 | struct add_rule<grammar_builder<Start, Rules, Actions>, P, no_action> : | |
338 | grammar_builder< | |
339 | Start, | |
340 | typename boost::mpl::insert<Rules, typename P::type>::type, | |
341 | Actions | |
342 | > | |
343 | {}; | |
344 | ||
345 | template <class Start, class Rules, class Actions, class P, class F> | |
346 | struct add_rule<grammar_builder<Start, Rules, Actions>, P, F> : | |
347 | grammar_builder< | |
348 | Start, | |
349 | typename boost::mpl::insert<Rules, typename P::type>::type, | |
350 | typename boost::mpl::insert< | |
351 | Actions, | |
352 | boost::mpl::pair< | |
353 | typename P::name, | |
354 | typename boost::mpl::lambda<F>::type | |
355 | > | |
356 | > | |
357 | ::type | |
358 | > | |
359 | {}; | |
360 | ||
361 | template <class Start, class Rules, class Actions, class Name, class P> | |
362 | struct add_import<grammar_builder<Start, Rules, Actions>, Name, P> : | |
363 | grammar_builder< | |
364 | Start, | |
365 | typename boost::mpl::insert< | |
366 | Rules, | |
367 | boost::mpl::pair<Name, build_native_parser<P> > | |
368 | >::type, | |
369 | Actions | |
370 | > | |
371 | {}; | |
372 | } | |
373 | ||
374 | template <class Start = string<'S'> > | |
375 | struct grammar : | |
376 | grammar_util::grammar_builder< | |
377 | Start, | |
378 | boost::mpl::map<>, | |
379 | boost::mpl::map<> | |
380 | > | |
381 | {}; | |
382 | } | |
383 | } | |
384 | } | |
385 | ||
386 | #endif |