annotate DEPENDENCIES/generic/include/boost/spirit/home/classic/utility/grammar_def.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 /*=============================================================================
Chris@16 2 Copyright (c) 2003 Hartmut Kaiser
Chris@16 3 Copyright (c) 2003 Joel de Guzman
Chris@16 4 http://spirit.sourceforge.net/
Chris@16 5
Chris@16 6 Distributed under the Boost Software License, Version 1.0. (See accompanying
Chris@16 7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 8 =============================================================================*/
Chris@16 9 #if !defined(BOOST_SPIRIT_GRAMMAR_DEF_HPP)
Chris@16 10 #define BOOST_SPIRIT_GRAMMAR_DEF_HPP
Chris@16 11
Chris@16 12 #include <boost/mpl/if.hpp>
Chris@16 13 #include <boost/mpl/eval_if.hpp>
Chris@16 14 #include <boost/type_traits/is_same.hpp>
Chris@16 15 #include <boost/preprocessor/arithmetic/inc.hpp>
Chris@16 16 #include <boost/preprocessor/arithmetic/dec.hpp>
Chris@16 17 #include <boost/preprocessor/enum.hpp>
Chris@16 18 #include <boost/preprocessor/enum_params.hpp>
Chris@16 19 #include <boost/preprocessor/repeat.hpp>
Chris@16 20 #include <boost/preprocessor/repeat_from_to.hpp>
Chris@16 21 #include <boost/spirit/home/classic/namespace.hpp>
Chris@16 22 #include <boost/spirit/home/classic/phoenix/tuples.hpp>
Chris@16 23 #include <boost/spirit/home/classic/core/assert.hpp>
Chris@16 24 #include <boost/spirit/home/classic/utility/grammar_def_fwd.hpp>
Chris@16 25
Chris@16 26 ///////////////////////////////////////////////////////////////////////////////
Chris@16 27 //
Chris@16 28 // Spirit predefined maximum grammar start parser limit. This limit defines
Chris@101 29 // the maximum number of possible different parsers exposed from a
Chris@16 30 // particular grammar. This number defaults to 3.
Chris@16 31 // The actual maximum is rounded up in multiples of 3. Thus, if this value
Chris@16 32 // is 4, the actual limit is 6. The ultimate maximum limit in this
Chris@16 33 // implementation is 15.
Chris@16 34 //
Chris@16 35 // It should NOT be greater than PHOENIX_LIMIT!
Chris@16 36 //
Chris@16 37 ///////////////////////////////////////////////////////////////////////////////
Chris@16 38 #if !defined(BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT)
Chris@16 39 #define BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT PHOENIX_LIMIT
Chris@16 40 #endif
Chris@16 41
Chris@16 42 ///////////////////////////////////////////////////////////////////////////////
Chris@16 43 //
Chris@16 44 // ensure BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT <= PHOENIX_LIMIT and
Chris@16 45 // BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT <= 15 and
Chris@16 46 // BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT > 0
Chris@16 47 //
Chris@16 48 ///////////////////////////////////////////////////////////////////////////////
Chris@16 49 BOOST_STATIC_ASSERT(BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT <= PHOENIX_LIMIT);
Chris@16 50 BOOST_STATIC_ASSERT(BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT <= 15);
Chris@16 51 BOOST_STATIC_ASSERT(BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT > 0);
Chris@16 52
Chris@16 53 //////////////////////////////////////////////////////////////////////////////
Chris@16 54 namespace boost { namespace spirit {
Chris@16 55
Chris@16 56 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
Chris@16 57
Chris@16 58 struct same {};
Chris@16 59
Chris@16 60 ///////////////////////////////////////////////////////////////////////////////
Chris@16 61 namespace impl {
Chris@16 62
Chris@16 63 ///////////////////////////////////////////////////////////////////////////
Chris@16 64 //
Chris@16 65 // The make_const_pointer meta function allows to generate a T const*
Chris@16 66 // needed to store the pointer to a given start parser from a grammar.
Chris@16 67 //
Chris@16 68 ///////////////////////////////////////////////////////////////////////////
Chris@16 69 template <typename T0, typename T = T0>
Chris@16 70 struct make_const_pointer {
Chris@16 71
Chris@16 72 private:
Chris@16 73 // T0 shouldn't be of type 'same'
Chris@16 74 BOOST_STATIC_ASSERT((!boost::is_same<T0, same>::value));
Chris@16 75
Chris@16 76 typedef typename boost::mpl::if_c<
Chris@16 77 boost::is_same<T, same>::value,
Chris@16 78 T0 const *,
Chris@16 79 T const *
Chris@16 80 >::type
Chris@16 81 ptr_type;
Chris@16 82
Chris@16 83 public:
Chris@16 84 // If the type in question is phoenix::nil_t, then the returned type
Chris@16 85 // is still phoenix::nil_t, otherwise a constant pointer type to the
Chris@16 86 // inspected type is returned.
Chris@16 87 typedef typename boost::mpl::if_c<
Chris@16 88 boost::is_same<T, ::phoenix::nil_t>::value,
Chris@16 89 ::phoenix::nil_t,
Chris@16 90 ptr_type
Chris@16 91 >::type
Chris@16 92 type;
Chris@16 93 };
Chris@16 94
Chris@16 95 ///////////////////////////////////////////////////////////////////////////
Chris@16 96 template <int N, typename ElementT>
Chris@16 97 struct assign_zero_to_tuple_member {
Chris@16 98
Chris@16 99 template <typename TupleT>
Chris@16 100 static void do_(TupleT &t) { t[::phoenix::tuple_index<N>()] = 0; }
Chris@16 101 };
Chris@16 102
Chris@16 103 template <int N>
Chris@16 104 struct assign_zero_to_tuple_member<N, ::phoenix::nil_t> {
Chris@16 105
Chris@16 106 template <typename TupleT>
Chris@16 107 static void do_(TupleT& /*t*/) {}
Chris@16 108 };
Chris@16 109
Chris@16 110 struct phoenix_nil_type {
Chris@16 111
Chris@16 112 typedef ::phoenix::nil_t type;
Chris@16 113 };
Chris@16 114
Chris@16 115 template <int N>
Chris@16 116 struct init_tuple_member {
Chris@16 117
Chris@16 118 template <typename TupleT>
Chris@16 119 static void
Chris@16 120 do_(TupleT &t)
Chris@16 121 {
Chris@16 122 typedef typename boost::mpl::eval_if_c<
Chris@16 123 (N < TupleT::length),
Chris@16 124 ::phoenix::tuple_element<N, TupleT>,
Chris@16 125 phoenix_nil_type
Chris@16 126 >::type
Chris@16 127 element_type;
Chris@16 128
Chris@16 129 assign_zero_to_tuple_member<N, element_type>::do_(t);
Chris@16 130 }
Chris@16 131 };
Chris@16 132
Chris@16 133 ///////////////////////////////////////////////////////////////////////////////
Chris@16 134 } // namespace impl
Chris@16 135
Chris@16 136 ///////////////////////////////////////////////////////////////////////////////
Chris@16 137 //
Chris@16 138 // grammar_def class
Chris@16 139 //
Chris@16 140 // This class may be used as a base class for the embedded definition
Chris@16 141 // class inside the grammar<> derived user grammar.
Chris@16 142 // It exposes the two functions needed for start rule access:
Chris@16 143 //
Chris@16 144 // rule<> const &start() const;
Chris@16 145 //
Chris@16 146 // and
Chris@16 147 //
Chris@16 148 // template <int N>
Chris@16 149 // rule<> const *get_start_parser() const;
Chris@16 150 //
Chris@16 151 // Additionally it exposes a set o 'start_parsers' functions, which are to
Chris@16 152 // be called by the user to define the parsers to use as start parsers
Chris@16 153 // of the given grammar.
Chris@16 154 //
Chris@16 155 ///////////////////////////////////////////////////////////////////////////////
Chris@16 156 template <
Chris@16 157 typename T,
Chris@16 158 BOOST_PP_ENUM_PARAMS(
Chris@16 159 BOOST_PP_DEC(BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT_A), typename T)
Chris@16 160 >
Chris@16 161 class grammar_def {
Chris@16 162
Chris@16 163 private:
Chris@16 164 ///////////////////////////////////////////////////////////////////////////
Chris@16 165 //
Chris@16 166 // This generates the full tuple type from the given template parameters
Chris@16 167 // T, T0, ...
Chris@16 168 //
Chris@16 169 // typedef ::phoenix::tuple<
Chris@16 170 // typename impl::make_const_pointer<T>::type,
Chris@16 171 // typename impl::make_const_pointer<T, T0>::type,
Chris@16 172 // ...
Chris@16 173 // > tuple_t;
Chris@16 174 //
Chris@16 175 ///////////////////////////////////////////////////////////////////////////
Chris@16 176 #define BOOST_SPIRIT_GRAMMARDEF_TUPLE_PARAM(z, N, _) \
Chris@16 177 typename impl::make_const_pointer<T, BOOST_PP_CAT(T, N)>::type \
Chris@16 178 /**/
Chris@16 179
Chris@16 180 typedef ::phoenix::tuple<
Chris@16 181 typename impl::make_const_pointer<T>::type,
Chris@16 182 BOOST_PP_ENUM(
Chris@16 183 BOOST_PP_DEC(BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT_A),
Chris@16 184 BOOST_SPIRIT_GRAMMARDEF_TUPLE_PARAM,
Chris@16 185 _
Chris@16 186 )
Chris@16 187 > tuple_t;
Chris@16 188
Chris@16 189 #undef BOOST_SPIRIT_GRAMMARDEF_TUPLE_PARAM
Chris@16 190 ///////////////////////////////////////////////////////////////////////////
Chris@16 191
Chris@16 192 protected:
Chris@16 193 ///////////////////////////////////////////////////////////////////////////
Chris@16 194 //
Chris@16 195 // This generates a sequence of 'start_parsers' functions with increasing
Chris@16 196 // number of arguments, which allow to initialize the tuple members with
Chris@16 197 // the pointers to the start parsers of the grammar:
Chris@16 198 //
Chris@16 199 // template <typename TC0, ...>
Chris@16 200 // void start_parsers (TC0 const &t0, ...)
Chris@16 201 // {
Chris@16 202 // using ::phoenix::tuple_index_names::_1;
Chris@16 203 // t[_1] = &t0;
Chris@16 204 // ...
Chris@16 205 // }
Chris@16 206 //
Chris@16 207 // where a TC0 const* must be convertible to a T0 const*
Chris@16 208 //
Chris@16 209 ///////////////////////////////////////////////////////////////////////////
Chris@16 210 #define BOOST_SPIRIT_GRAMMARDEF_ENUM_PARAMS(z, N, _) \
Chris@16 211 BOOST_PP_CAT(TC, N) const &BOOST_PP_CAT(t, N) \
Chris@16 212 /**/
Chris@16 213 #define BOOST_SPIRIT_GRAMMARDEF_ENUM_ASSIGN(z, N, _) \
Chris@16 214 using ::phoenix::tuple_index_names::BOOST_PP_CAT(_, BOOST_PP_INC(N)); \
Chris@16 215 t[BOOST_PP_CAT(_, BOOST_PP_INC(N))] = &BOOST_PP_CAT(t, N); \
Chris@16 216 /**/
Chris@16 217 #define BOOST_SPIRIT_GRAMMARDEF_ENUM_START(z, N, _) \
Chris@16 218 template <BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), typename TC)> \
Chris@16 219 void \
Chris@16 220 start_parsers(BOOST_PP_ENUM_ ## z(BOOST_PP_INC(N), \
Chris@16 221 BOOST_SPIRIT_GRAMMARDEF_ENUM_PARAMS, _) ) \
Chris@16 222 { \
Chris@16 223 BOOST_PP_REPEAT_ ## z(BOOST_PP_INC(N), \
Chris@16 224 BOOST_SPIRIT_GRAMMARDEF_ENUM_ASSIGN, _) \
Chris@16 225 } \
Chris@16 226 /**/
Chris@16 227
Chris@16 228 BOOST_PP_REPEAT(
Chris@16 229 BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT_A,
Chris@16 230 BOOST_SPIRIT_GRAMMARDEF_ENUM_START, _)
Chris@16 231
Chris@16 232 #undef BOOST_SPIRIT_GRAMMARDEF_ENUM_START
Chris@16 233 #undef BOOST_SPIRIT_GRAMMARDEF_ENUM_ASSIGN
Chris@16 234 #undef BOOST_SPIRIT_GRAMMARDEF_ENUM_PARAMS
Chris@16 235 ///////////////////////////////////////////////////////////////////////////
Chris@16 236
Chris@16 237 ///////////////////////////////////////////////////////////////////////////
Chris@16 238 //
Chris@16 239 // This generates some initialization code, which allows to initialize all
Chris@16 240 // used tuple members to 0 (zero):
Chris@16 241 //
Chris@16 242 // t[_1] = 0;
Chris@16 243 // impl::init_tuple_member<1>::do_(t);
Chris@16 244 // ...
Chris@16 245 //
Chris@16 246 ///////////////////////////////////////////////////////////////////////////
Chris@16 247 #define BOOST_SPIRIT_GRAMMARDEF_ENUM_INIT(z, N, _) \
Chris@16 248 impl::init_tuple_member<N>::do_(t); \
Chris@16 249 /**/
Chris@16 250
Chris@16 251 grammar_def()
Chris@16 252 {
Chris@16 253 using ::phoenix::tuple_index_names::_1;
Chris@16 254 t[_1] = 0;
Chris@16 255 BOOST_PP_REPEAT_FROM_TO(
Chris@16 256 1, BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT_A,
Chris@16 257 BOOST_SPIRIT_GRAMMARDEF_ENUM_INIT, _)
Chris@16 258 }
Chris@16 259
Chris@16 260 #undef BOOST_SPIRIT_GRAMMARDEF_ENUM_INIT
Chris@16 261 ///////////////////////////////////////////////////////////////////////////
Chris@16 262
Chris@16 263 public:
Chris@16 264 T const &
Chris@16 265 start() const
Chris@16 266 {
Chris@16 267 // If the following assertion is fired, you have probably forgot to call
Chris@16 268 // the start_parser() function from inside the constructor of your
Chris@16 269 // embedded definition class to initialize the start parsers to be exposed
Chris@16 270 // from your grammar.
Chris@16 271 using ::phoenix::tuple_index_names::_1;
Chris@16 272 BOOST_SPIRIT_ASSERT(0 != t[_1]);
Chris@16 273 return *t[_1];
Chris@16 274 }
Chris@16 275
Chris@16 276 template <int N>
Chris@16 277 typename ::phoenix::tuple_element<N, tuple_t>::crtype
Chris@16 278 get_start_parser() const
Chris@16 279 {
Chris@16 280 // If the following expression yields a compiler error, you have probably
Chris@16 281 // tried to access a start rule, which isn't exposed as such from your
Chris@16 282 // grammar.
Chris@16 283 BOOST_STATIC_ASSERT(N > 0 && N < tuple_t::length);
Chris@16 284
Chris@16 285 // If the following assertion is fired, you have probably forgot to call
Chris@16 286 // the start_parser() function from inside the constructor of your
Chris@16 287 // embedded definition class to initialize the start parsers to be exposed
Chris@16 288 // from your grammar.
Chris@16 289 // Another reason may be, that there is a count mismatch between
Chris@16 290 // the number of template parameters to the grammar_def<> class and the
Chris@16 291 // number of parameters used while calling start_parsers().
Chris@16 292 BOOST_SPIRIT_ASSERT(0 != t[::phoenix::tuple_index<N>()]);
Chris@16 293
Chris@16 294 return t[::phoenix::tuple_index<N>()];
Chris@16 295 }
Chris@16 296
Chris@16 297 private:
Chris@16 298 tuple_t t;
Chris@16 299 };
Chris@16 300
Chris@16 301 #undef BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT_A
Chris@16 302
Chris@16 303 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
Chris@16 304
Chris@16 305 }} // namespace BOOST_SPIRIT_CLASSIC_NS
Chris@16 306
Chris@16 307 #endif // BOOST_SPIRIT_GRAMMAR_DEF_HPP