text: #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
  