File indexing completed on 2025-01-31 10:02:08
0001
0002
0003
0004
0005
0006
0007
0008
0009 #if !defined(BOOST_SPIRIT_GRAMMAR_DEF_HPP)
0010 #define BOOST_SPIRIT_GRAMMAR_DEF_HPP
0011
0012 #include <boost/mpl/if.hpp>
0013 #include <boost/mpl/eval_if.hpp>
0014 #include <boost/type_traits/is_same.hpp>
0015 #include <boost/preprocessor/arithmetic/inc.hpp>
0016 #include <boost/preprocessor/arithmetic/dec.hpp>
0017 #include <boost/preprocessor/enum.hpp>
0018 #include <boost/preprocessor/enum_params.hpp>
0019 #include <boost/preprocessor/repeat.hpp>
0020 #include <boost/preprocessor/repeat_from_to.hpp>
0021 #include <boost/spirit/home/classic/namespace.hpp>
0022 #include <boost/spirit/home/classic/phoenix/tuples.hpp>
0023 #include <boost/spirit/home/classic/core/assert.hpp>
0024 #include <boost/spirit/home/classic/utility/grammar_def_fwd.hpp>
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 #if !defined(BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT)
0039 #define BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT PHOENIX_LIMIT
0040 #endif
0041
0042
0043
0044
0045
0046
0047
0048
0049 BOOST_STATIC_ASSERT(BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT <= PHOENIX_LIMIT);
0050 BOOST_STATIC_ASSERT(BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT <= 15);
0051 BOOST_STATIC_ASSERT(BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT > 0);
0052
0053
0054 namespace boost { namespace spirit {
0055
0056 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
0057
0058 struct same {};
0059
0060
0061 namespace impl {
0062
0063
0064
0065
0066
0067
0068
0069 template <typename T0, typename T = T0>
0070 struct make_const_pointer {
0071
0072 private:
0073
0074 BOOST_STATIC_ASSERT((!boost::is_same<T0, same>::value));
0075
0076 typedef typename boost::mpl::if_c<
0077 boost::is_same<T, same>::value,
0078 T0 const *,
0079 T const *
0080 >::type
0081 ptr_type;
0082
0083 public:
0084
0085
0086
0087 typedef typename boost::mpl::if_c<
0088 boost::is_same<T, ::phoenix::nil_t>::value,
0089 ::phoenix::nil_t,
0090 ptr_type
0091 >::type
0092 type;
0093 };
0094
0095
0096 template <int N, typename ElementT>
0097 struct assign_zero_to_tuple_member {
0098
0099 template <typename TupleT>
0100 static void do_(TupleT &t)
0101 {
0102 ::phoenix::tuple_index<N> const idx;
0103 t[idx] = 0;
0104 }
0105 };
0106
0107 template <int N>
0108 struct assign_zero_to_tuple_member<N, ::phoenix::nil_t> {
0109
0110 template <typename TupleT>
0111 static void do_(TupleT& ) {}
0112 };
0113
0114 struct phoenix_nil_type {
0115
0116 typedef ::phoenix::nil_t type;
0117 };
0118
0119 template <int N>
0120 struct init_tuple_member {
0121
0122 template <typename TupleT>
0123 static void
0124 do_(TupleT &t)
0125 {
0126 typedef typename boost::mpl::eval_if_c<
0127 (N < TupleT::length),
0128 ::phoenix::tuple_element<N, TupleT>,
0129 phoenix_nil_type
0130 >::type
0131 element_type;
0132
0133 assign_zero_to_tuple_member<N, element_type>::do_(t);
0134 }
0135 };
0136
0137
0138 }
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160 template <
0161 typename T,
0162 BOOST_PP_ENUM_PARAMS(
0163 BOOST_PP_DEC(BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT_A), typename T)
0164 >
0165 class grammar_def {
0166
0167 private:
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180 #define BOOST_SPIRIT_GRAMMARDEF_TUPLE_PARAM(z, N, _) \
0181 typename impl::make_const_pointer<T, BOOST_PP_CAT(T, N)>::type \
0182
0183
0184 typedef ::phoenix::tuple<
0185 typename impl::make_const_pointer<T>::type,
0186 BOOST_PP_ENUM(
0187 BOOST_PP_DEC(BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT_A),
0188 BOOST_SPIRIT_GRAMMARDEF_TUPLE_PARAM,
0189 _
0190 )
0191 > tuple_t;
0192
0193 #undef BOOST_SPIRIT_GRAMMARDEF_TUPLE_PARAM
0194
0195
0196 protected:
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214 #define BOOST_SPIRIT_GRAMMARDEF_ENUM_PARAMS(z, N, _) \
0215 BOOST_PP_CAT(TC, N) const &BOOST_PP_CAT(t, N) \
0216
0217 #define BOOST_SPIRIT_GRAMMARDEF_ENUM_ASSIGN(z, N, _) \
0218 using ::phoenix::tuple_index_names::BOOST_PP_CAT(_, BOOST_PP_INC(N)); \
0219 t[BOOST_PP_CAT(_, BOOST_PP_INC(N))] = &BOOST_PP_CAT(t, N); \
0220
0221 #define BOOST_SPIRIT_GRAMMARDEF_ENUM_START(z, N, _) \
0222 template <BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), typename TC)> \
0223 void \
0224 start_parsers(BOOST_PP_ENUM_ ## z(BOOST_PP_INC(N), \
0225 BOOST_SPIRIT_GRAMMARDEF_ENUM_PARAMS, _) ) \
0226 { \
0227 BOOST_PP_REPEAT_ ## z(BOOST_PP_INC(N), \
0228 BOOST_SPIRIT_GRAMMARDEF_ENUM_ASSIGN, _) \
0229 } \
0230
0231
0232 BOOST_PP_REPEAT(
0233 BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT_A,
0234 BOOST_SPIRIT_GRAMMARDEF_ENUM_START, _)
0235
0236 #undef BOOST_SPIRIT_GRAMMARDEF_ENUM_START
0237 #undef BOOST_SPIRIT_GRAMMARDEF_ENUM_ASSIGN
0238 #undef BOOST_SPIRIT_GRAMMARDEF_ENUM_PARAMS
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251 #define BOOST_SPIRIT_GRAMMARDEF_ENUM_INIT(z, N, _) \
0252 impl::init_tuple_member<N>::do_(t); \
0253
0254
0255 grammar_def()
0256 {
0257 using ::phoenix::tuple_index_names::_1;
0258 t[_1] = 0;
0259 BOOST_PP_REPEAT_FROM_TO(
0260 1, BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT_A,
0261 BOOST_SPIRIT_GRAMMARDEF_ENUM_INIT, _)
0262 }
0263
0264 #undef BOOST_SPIRIT_GRAMMARDEF_ENUM_INIT
0265
0266
0267 public:
0268 T const &
0269 start() const
0270 {
0271
0272
0273
0274
0275 using ::phoenix::tuple_index_names::_1;
0276 BOOST_SPIRIT_ASSERT(0 != t[_1]);
0277 return *t[_1];
0278 }
0279
0280 template <int N>
0281 typename ::phoenix::tuple_element<N, tuple_t>::crtype
0282 get_start_parser() const
0283 {
0284
0285
0286
0287 BOOST_STATIC_ASSERT(N > 0 && N < tuple_t::length);
0288
0289 ::phoenix::tuple_index<N> const idx;
0290
0291
0292
0293
0294
0295
0296
0297
0298 BOOST_SPIRIT_ASSERT(0 != t[idx]);
0299
0300 return t[idx];
0301 }
0302
0303 private:
0304 tuple_t t;
0305 };
0306
0307 #undef BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT_A
0308
0309 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
0310
0311 }}
0312
0313 #endif