1 #ifndef BOOST_METAPARSE_V1_GRAMMAR_HPP
2 #define BOOST_METAPARSE_V1_GRAMMAR_HPP
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)
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>
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>
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
57 namespace grammar_util
59 template <char Op, class FState>
60 struct repeated_apply_impl
62 typedef repeated_apply_impl type;
66 repeated<typename FState::template apply<G>::type>
70 template <class FState>
71 struct repeated_apply_impl<'+', FState>
73 typedef repeated_apply_impl type;
77 repeated1<typename FState::template apply<G>::type>
83 typedef build_repeated type;
85 template <class FState, class T>
86 struct apply : repeated_apply_impl<T::type::value, FState> {};
91 typedef build_sequence type;
93 template <class FState, class FP>
96 typedef apply_impl type;
101 typename FState::template apply<G>::type,
102 typename FP::template apply<G>::type
107 template <class FState, class FP>
108 struct apply : apply_impl<FState, FP> {};
111 struct build_selection
113 typedef build_selection type;
115 template <class FState, class FP>
118 typedef apply_impl type;
123 typename FState::template apply<G>::type,
124 typename FP::template apply<G>::type
129 template <class FState, class FP>
130 struct apply : apply_impl<FState, FP> {};
133 template <class G, class Name>
137 typename boost::mpl::at<typename G::rules, Name>::type
141 template <class Actions>
142 struct impl : transform<typename p::type, typename Actions::type> {};
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> >,
155 typedef build_name type;
157 template <class Name>
160 typedef apply_impl type;
163 struct apply : get_parser<G, Name> {};
166 template <class Name>
167 struct apply : apply_impl<Name> {};
172 typedef build_char type;
177 typedef apply_impl type;
180 struct apply : lit<C> {};
184 struct apply : apply_impl<C> {};
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;
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'> >,
208 one_char_except_c<'\''>
217 one_of<alphanum, lit_c<'_'> >,
227 middle_of<open_bracket_token, expression, close_bracket_token>
232 transform<char_token, build_char>,
233 transform<name_token, build_name>,
239 foldl_start_with_parser<
240 one_of<repeated_token, repeated1_token>,
247 foldl_start_with_parser<
255 foldl_start_with_parser<
256 last_of<or_token, seq_expression>,
262 typedef sequence<name_token, define_token, expression> rule_definition;
264 typedef build_parser<entire_input<rule_definition> > parser_parser;
267 struct build_native_parser
269 typedef build_native_parser type;
279 struct build_parsed_parser
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;
287 typedef the_parser type;
290 struct apply : exp::template apply<G> {};
293 typedef boost::mpl::pair<name, the_parser> type;
296 typedef build_parser<name_token> name_parser;
299 struct rebuild : name_parser::template apply<S> {};
303 template <class G, class P, class F>
306 template <class G, class Name, class P>
309 template <class Start, class Rules, class Actions>
310 struct grammar_builder
312 typedef grammar_builder type;
314 typedef Actions actions;
317 template <class S, class Pos>
321 typename rebuild<Start>::type
322 >::type::template apply<S, Pos>
325 template <class Name, class P>
327 add_import<grammar_builder, typename rebuild<Name>::type, P>
330 template <class Def, class Action = no_action>
332 add_rule<grammar_builder, build_parsed_parser<Def>, Action>
336 template <class Start, class Rules, class Actions, class P>
337 struct add_rule<grammar_builder<Start, Rules, Actions>, P, no_action> :
340 typename boost::mpl::insert<Rules, typename P::type>::type,
345 template <class Start, class Rules, class Actions, class P, class F>
346 struct add_rule<grammar_builder<Start, Rules, Actions>, P, F> :
349 typename boost::mpl::insert<Rules, typename P::type>::type,
350 typename boost::mpl::insert<
354 typename boost::mpl::lambda<F>::type
361 template <class Start, class Rules, class Actions, class Name, class P>
362 struct add_import<grammar_builder<Start, Rules, Actions>, Name, P> :
365 typename boost::mpl::insert<
367 boost::mpl::pair<Name, build_native_parser<P> >
374 template <class Start = string<'S'> >
376 grammar_util::grammar_builder<