summaryrefslogtreecommitdiff
path: root/boost/metaparse/v1/grammar.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/metaparse/v1/grammar.hpp')
-rw-r--r--boost/metaparse/v1/grammar.hpp386
1 files changed, 386 insertions, 0 deletions
diff --git a/boost/metaparse/v1/grammar.hpp b/boost/metaparse/v1/grammar.hpp
new file mode 100644
index 0000000000..6f885345d5
--- /dev/null
+++ b/boost/metaparse/v1/grammar.hpp
@@ -0,0 +1,386 @@
+#ifndef BOOST_METAPARSE_V1_GRAMMAR_HPP
+#define BOOST_METAPARSE_V1_GRAMMAR_HPP
+
+// Copyright Abel Sinkovics (abel@sinkovics.hu) 2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/metaparse/v1/repeated.hpp>
+#include <boost/metaparse/v1/repeated1.hpp>
+#include <boost/metaparse/v1/sequence.hpp>
+#include <boost/metaparse/v1/one_of.hpp>
+#include <boost/metaparse/v1/transform.hpp>
+#include <boost/metaparse/v1/lit.hpp>
+#include <boost/metaparse/v1/lit_c.hpp>
+#include <boost/metaparse/v1/token.hpp>
+#include <boost/metaparse/v1/keyword.hpp>
+#include <boost/metaparse/v1/middle_of.hpp>
+#include <boost/metaparse/v1/last_of.hpp>
+#include <boost/metaparse/v1/always.hpp>
+#include <boost/metaparse/v1/one_char_except_c.hpp>
+#include <boost/metaparse/v1/foldr1.hpp>
+#include <boost/metaparse/v1/foldl_start_with_parser.hpp>
+#include <boost/metaparse/v1/alphanum.hpp>
+#include <boost/metaparse/v1/build_parser.hpp>
+#include <boost/metaparse/v1/entire_input.hpp>
+#include <boost/metaparse/v1/string.hpp>
+#include <boost/metaparse/v1/impl/front_inserter.hpp>
+
+#include <boost/mpl/at.hpp>
+#include <boost/mpl/map.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/has_key.hpp>
+#include <boost/mpl/lambda.hpp>
+#include <boost/mpl/front.hpp>
+#include <boost/mpl/back.hpp>
+#include <boost/mpl/pair.hpp>
+#include <boost/mpl/insert.hpp>
+
+/*
+ * The grammar
+ *
+ * rule_definition ::= name_token define_token expression
+ * expression ::= seq_expression (or_token seq_expression)*
+ * seq_expression ::= repeated_expression+
+ * repeated_expression ::= name_expression (repeated_token | repeated1_token)*
+ * name_expression ::= char_token | name_token | bracket_expression
+ * bracket_expression ::= open_bracket_token expression close_bracket_token
+ */
+
+namespace boost
+{
+ namespace metaparse
+ {
+ namespace v1
+ {
+ namespace grammar_util
+ {
+ template <char Op, class FState>
+ struct repeated_apply_impl
+ {
+ typedef repeated_apply_impl type;
+
+ template <class G>
+ struct apply :
+ repeated<typename FState::template apply<G>::type>
+ {};
+ };
+
+ template <class FState>
+ struct repeated_apply_impl<'+', FState>
+ {
+ typedef repeated_apply_impl type;
+
+ template <class G>
+ struct apply :
+ repeated1<typename FState::template apply<G>::type>
+ {};
+ };
+
+ struct build_repeated
+ {
+ typedef build_repeated type;
+
+ template <class FState, class T>
+ struct apply : repeated_apply_impl<T::type::value, FState> {};
+ };
+
+ struct build_sequence
+ {
+ typedef build_sequence type;
+
+ template <class FState, class FP>
+ struct apply_impl
+ {
+ typedef apply_impl type;
+
+ template <class G>
+ struct apply :
+ sequence<
+ typename FState::template apply<G>::type,
+ typename FP::template apply<G>::type
+ >
+ {};
+ };
+
+ template <class FState, class FP>
+ struct apply : apply_impl<FState, FP> {};
+ };
+
+ struct build_selection
+ {
+ typedef build_selection type;
+
+ template <class FState, class FP>
+ struct apply_impl
+ {
+ typedef apply_impl type;
+
+ template <class G>
+ struct apply :
+ one_of<
+ typename FState::template apply<G>::type,
+ typename FP::template apply<G>::type
+ >
+ {};
+ };
+
+ template <class FState, class FP>
+ struct apply : apply_impl<FState, FP> {};
+ };
+
+ template <class G, class Name>
+ struct get_parser
+ {
+ typedef
+ typename boost::mpl::at<typename G::rules, Name>::type
+ ::template apply<G>
+ p;
+
+ template <class Actions>
+ struct impl : transform<typename p::type, typename Actions::type> {};
+
+ typedef
+ typename boost::mpl::eval_if<
+ typename boost::mpl::has_key<typename G::actions, Name>::type,
+ impl<boost::mpl::at<typename G::actions, Name> >,
+ p
+ >::type
+ type;
+ };
+
+ struct build_name
+ {
+ typedef build_name type;
+
+ template <class Name>
+ struct apply_impl
+ {
+ typedef apply_impl type;
+
+ template <class G>
+ struct apply : get_parser<G, Name> {};
+ };
+
+ template <class Name>
+ struct apply : apply_impl<Name> {};
+ };
+
+ struct build_char
+ {
+ typedef build_char type;
+
+ template <class C>
+ struct apply_impl
+ {
+ typedef apply_impl type;
+
+ template <class G>
+ struct apply : lit<C> {};
+ };
+
+ template <class C>
+ struct apply : apply_impl<C> {};
+ };
+
+ typedef token<lit_c<'*'> > repeated_token;
+ typedef token<lit_c<'+'> > repeated1_token;
+ typedef token<lit_c<'|'> > or_token;
+ typedef token<lit_c<'('> > open_bracket_token;
+ typedef token<lit_c<')'> > close_bracket_token;
+ typedef token<keyword<string<':',':','='> > > define_token;
+
+ typedef
+ middle_of<
+ lit_c<'\''>,
+ one_of<
+ last_of<
+ lit_c<'\\'>,
+ one_of<
+ always<lit_c<'n'>, boost::mpl::char_<'\n'> >,
+ always<lit_c<'r'>, boost::mpl::char_<'\r'> >,
+ always<lit_c<'t'>, boost::mpl::char_<'\t'> >,
+ lit_c<'\\'>,
+ lit_c<'\''>
+ >
+ >,
+ one_char_except_c<'\''>
+ >,
+ token<lit_c<'\''> >
+ >
+ char_token;
+
+ typedef
+ token<
+ foldr1<
+ one_of<alphanum, lit_c<'_'> >,
+ string<>,
+ impl::front_inserter
+ >
+ >
+ name_token;
+
+ struct expression;
+
+ typedef
+ middle_of<open_bracket_token, expression, close_bracket_token>
+ bracket_expression;
+
+ typedef
+ one_of<
+ transform<char_token, build_char>,
+ transform<name_token, build_name>,
+ bracket_expression
+ >
+ name_expression;
+
+ typedef
+ foldl_start_with_parser<
+ one_of<repeated_token, repeated1_token>,
+ name_expression,
+ build_repeated
+ >
+ repeated_expression;
+
+ typedef
+ foldl_start_with_parser<
+ repeated_expression,
+ repeated_expression,
+ build_sequence
+ >
+ seq_expression;
+
+ struct expression :
+ foldl_start_with_parser<
+ last_of<or_token, seq_expression>,
+ seq_expression,
+ build_selection
+ >
+ {};
+
+ typedef sequence<name_token, define_token, expression> rule_definition;
+
+ typedef build_parser<entire_input<rule_definition> > parser_parser;
+
+ template <class P>
+ struct build_native_parser
+ {
+ typedef build_native_parser type;
+
+ template <class G>
+ struct apply
+ {
+ typedef P type;
+ };
+ };
+
+ template <class S>
+ struct build_parsed_parser
+ {
+ typedef typename parser_parser::apply<S>::type p;
+ typedef typename boost::mpl::front<p>::type name;
+ typedef typename boost::mpl::back<p>::type exp;
+
+ struct the_parser
+ {
+ typedef the_parser type;
+
+ template <class G>
+ struct apply : exp::template apply<G> {};
+ };
+
+ typedef boost::mpl::pair<name, the_parser> type;
+ };
+
+ typedef build_parser<name_token> name_parser;
+
+ template <class S>
+ struct rebuild : name_parser::template apply<S> {};
+
+ struct no_action;
+
+ template <class G, class P, class F>
+ struct add_rule;
+
+ template <class G, class Name, class P>
+ struct add_import;
+
+ template <class Start, class Rules, class Actions>
+ struct grammar_builder
+ {
+ typedef grammar_builder type;
+ typedef Rules rules;
+ typedef Actions actions;
+
+ // Make it a parser
+ template <class S, class Pos>
+ struct apply :
+ get_parser<
+ grammar_builder,
+ typename rebuild<Start>::type
+ >::type::template apply<S, Pos>
+ {};
+
+ template <class Name, class P>
+ struct import :
+ add_import<grammar_builder, typename rebuild<Name>::type, P>
+ {};
+
+ template <class Def, class Action = no_action>
+ struct rule :
+ add_rule<grammar_builder, build_parsed_parser<Def>, Action>
+ {};
+ };
+
+ template <class Start, class Rules, class Actions, class P>
+ struct add_rule<grammar_builder<Start, Rules, Actions>, P, no_action> :
+ grammar_builder<
+ Start,
+ typename boost::mpl::insert<Rules, typename P::type>::type,
+ Actions
+ >
+ {};
+
+ template <class Start, class Rules, class Actions, class P, class F>
+ struct add_rule<grammar_builder<Start, Rules, Actions>, P, F> :
+ grammar_builder<
+ Start,
+ typename boost::mpl::insert<Rules, typename P::type>::type,
+ typename boost::mpl::insert<
+ Actions,
+ boost::mpl::pair<
+ typename P::name,
+ typename boost::mpl::lambda<F>::type
+ >
+ >
+ ::type
+ >
+ {};
+
+ template <class Start, class Rules, class Actions, class Name, class P>
+ struct add_import<grammar_builder<Start, Rules, Actions>, Name, P> :
+ grammar_builder<
+ Start,
+ typename boost::mpl::insert<
+ Rules,
+ boost::mpl::pair<Name, build_native_parser<P> >
+ >::type,
+ Actions
+ >
+ {};
+ }
+
+ template <class Start = string<'S'> >
+ struct grammar :
+ grammar_util::grammar_builder<
+ Start,
+ boost::mpl::map<>,
+ boost::mpl::map<>
+ >
+ {};
+ }
+ }
+}
+
+#endif