File indexing completed on 2025-01-31 10:01:55
0001
0002
0003
0004
0005
0006
0007
0008
0009 #if !defined(BOOST_SPIRIT_SUBRULE_HPP)
0010 #define BOOST_SPIRIT_SUBRULE_HPP
0011
0012 #include <boost/config.hpp>
0013 #include <boost/static_assert.hpp>
0014 #include <boost/mpl/if.hpp>
0015 #include <boost/mpl/bool.hpp>
0016 #include <boost/type_traits/is_same.hpp>
0017
0018 #include <boost/spirit/home/classic/namespace.hpp>
0019 #include <boost/spirit/home/classic/core/parser.hpp>
0020 #include <boost/spirit/home/classic/core/non_terminal/parser_context.hpp>
0021
0022 #include <boost/spirit/home/classic/core/non_terminal/subrule_fwd.hpp>
0023 #include <boost/spirit/home/classic/core/non_terminal/impl/subrule.ipp>
0024
0025 namespace boost { namespace spirit {
0026
0027 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
0028
0029
0030
0031
0032
0033
0034 template <typename ScannerT, typename ListT>
0035 struct subrules_scanner : public ScannerT
0036 {
0037 typedef ScannerT scanner_t;
0038 typedef ListT list_t;
0039 typedef subrules_scanner<ScannerT, ListT> self_t;
0040
0041 subrules_scanner(ScannerT const& scan, ListT const& list_)
0042 : ScannerT(scan), list(list_) {}
0043
0044 template <typename PoliciesT>
0045 struct rebind_policies
0046 {
0047 typedef typename rebind_scanner_policies<ScannerT, PoliciesT>::type
0048 rebind_scanner;
0049 typedef subrules_scanner<rebind_scanner, ListT> type;
0050 };
0051
0052 template <typename PoliciesT>
0053 subrules_scanner<
0054 typename rebind_scanner_policies<ScannerT, PoliciesT>::type,
0055 ListT>
0056 change_policies(PoliciesT const& policies) const
0057 {
0058 typedef subrules_scanner<
0059 BOOST_DEDUCED_TYPENAME
0060 rebind_scanner_policies<ScannerT, PoliciesT>::type,
0061 ListT>
0062 subrules_scanner_t;
0063
0064 return subrules_scanner_t(
0065 ScannerT::change_policies(policies),
0066 list);
0067 }
0068
0069 template <typename IteratorT>
0070 struct rebind_iterator
0071 {
0072 typedef typename rebind_scanner_iterator<ScannerT, IteratorT>::type
0073 rebind_scanner;
0074 typedef subrules_scanner<rebind_scanner, ListT> type;
0075 };
0076
0077 template <typename IteratorT>
0078 subrules_scanner<
0079 typename rebind_scanner_iterator<ScannerT, IteratorT>::type,
0080 ListT>
0081 change_iterator(IteratorT const& first, IteratorT const &last) const
0082 {
0083 typedef subrules_scanner<
0084 BOOST_DEDUCED_TYPENAME
0085 rebind_scanner_iterator<ScannerT, IteratorT>::type,
0086 ListT>
0087 subrules_scanner_t;
0088
0089 return subrules_scanner_t(
0090 ScannerT::change_iterator(first, last),
0091 list);
0092 }
0093
0094 ListT const& list;
0095 };
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105 template <typename ScannerT, typename ListT>
0106 struct subrules_scanner_finder
0107 {
0108 typedef subrules_scanner<ScannerT, ListT> type;
0109 };
0110
0111 template <typename ScannerT, typename ListT>
0112 struct subrules_scanner_finder<subrules_scanner<ScannerT, ListT>, ListT>
0113 {
0114 typedef subrules_scanner<ScannerT, ListT> type;
0115 };
0116
0117
0118
0119
0120
0121
0122 template <typename FirstT, typename RestT>
0123 struct subrule_list : public parser<subrule_list<FirstT, RestT> >
0124 {
0125 typedef subrule_list<FirstT, RestT> self_t;
0126 typedef FirstT first_t;
0127 typedef RestT rest_t;
0128
0129 subrule_list(FirstT const& first_, RestT const& rest_)
0130 : first(first_), rest(rest_) {}
0131
0132 template <typename ScannerT>
0133 struct result
0134 {
0135 typedef typename parser_result<FirstT, ScannerT>::type type;
0136 };
0137
0138 template <typename ScannerT>
0139 typename parser_result<self_t, ScannerT>::type
0140 parse(ScannerT const& scan) const
0141 {
0142 typedef typename subrules_scanner_finder<ScannerT, self_t>::type
0143 subrules_scanner_t;
0144 subrules_scanner_t g_arg(scan, *this);
0145 return first.start.parse(g_arg);
0146 }
0147
0148 template <int ID, typename DefT, typename ContextT>
0149 subrule_list<
0150 FirstT,
0151 subrule_list<
0152 subrule_parser<ID, DefT, ContextT>,
0153 RestT> >
0154 operator,(subrule_parser<ID, DefT, ContextT> const& rhs_)
0155 {
0156 return subrule_list<
0157 FirstT,
0158 subrule_list<
0159 subrule_parser<ID, DefT, ContextT>,
0160 RestT> >(
0161 first,
0162 subrule_list<
0163 subrule_parser<ID, DefT, ContextT>,
0164 RestT>(rhs_, rest));
0165 }
0166
0167 FirstT first;
0168 RestT rest;
0169 };
0170
0171
0172
0173
0174
0175
0176 template <int ID, typename DefT, typename ContextT>
0177 struct subrule_parser
0178 : public parser<subrule_parser<ID, DefT, ContextT> >
0179 {
0180 typedef subrule_parser<ID, DefT, ContextT> self_t;
0181 typedef subrule<ID, ContextT> subrule_t;
0182 typedef DefT def_t;
0183
0184 BOOST_STATIC_CONSTANT(int, id = ID);
0185
0186 template <typename ScannerT>
0187 struct result
0188 {
0189 typedef typename
0190 impl::get_subrule_parser_result<
0191 DefT, ScannerT, typename subrule_t::attr_t>::type type;
0192 };
0193
0194 subrule_parser(subrule_t const& start_, DefT const& rhs_)
0195 : rhs(rhs_), start(start_) {}
0196
0197 template <typename ScannerT>
0198 typename parser_result<self_t, ScannerT>::type
0199 parse(ScannerT const& scan) const
0200 {
0201
0202 typedef subrule_list<self_t, nil_t> list_t;
0203 typedef subrules_scanner<ScannerT, list_t> scanner_t;
0204
0205 list_t list(*this, nil_t());
0206 scanner_t g_arg(scan, list);
0207 return start.parse(g_arg);
0208 }
0209
0210 template <int ID2, typename DefT2, typename ContextT2>
0211 inline subrule_list<
0212 self_t,
0213 subrule_list<
0214 subrule_parser<ID2, DefT2, ContextT2>,
0215 nil_t> >
0216 operator,(subrule_parser<ID2, DefT2, ContextT2> const& rhs) const
0217 {
0218 return subrule_list<
0219 self_t,
0220 subrule_list<
0221 subrule_parser<ID2, DefT2, ContextT2>,
0222 nil_t> >(
0223 *this,
0224 subrule_list<
0225 subrule_parser<ID2, DefT2, ContextT2>, nil_t>(
0226 rhs, nil_t()));
0227 }
0228
0229 typename DefT::embed_t rhs;
0230 subrule_t const& start;
0231 };
0232
0233
0234
0235
0236
0237
0238 template <int ID, typename ContextT>
0239 struct subrule
0240 : public parser<subrule<ID, ContextT> >
0241 , public ContextT::base_t
0242 , public context_aux<ContextT, subrule<ID, ContextT> >
0243 {
0244 typedef subrule<ID, ContextT> self_t;
0245 typedef subrule<ID, ContextT> const& embed_t;
0246
0247 typedef typename ContextT::context_linker_t context_t;
0248 typedef typename context_t::attr_t attr_t;
0249
0250 BOOST_STATIC_CONSTANT(int, id = ID);
0251
0252 template <typename ScannerT>
0253 struct result
0254 {
0255 typedef typename
0256 impl::get_subrule_result<ID, ScannerT, attr_t>::type type;
0257 };
0258
0259 template <typename ScannerT>
0260 typename parser_result<self_t, ScannerT>::type
0261 parse_main(ScannerT const& scan) const
0262 {
0263 typedef typename parser_result<self_t, ScannerT>::type result_t;
0264 result_t result_;
0265 impl::parse_subrule<result_t, ScannerT, ID>::
0266 do_(result_, scan);
0267 return result_;
0268 }
0269
0270 template <typename ScannerT>
0271 typename parser_result<self_t, ScannerT>::type
0272 parse(ScannerT const& scan) const
0273 {
0274 typedef typename parser_result<self_t, ScannerT>::type result_t;
0275 typedef parser_scanner_linker<ScannerT> scanner_t;
0276 BOOST_SPIRIT_CONTEXT_PARSE(
0277 scan, *this, scanner_t, context_t, result_t);
0278 }
0279
0280 template <typename DefT>
0281 subrule_parser<ID, DefT, ContextT>
0282 operator=(parser<DefT> const& rhs) const
0283 {
0284 return subrule_parser<ID, DefT, ContextT>(*this, rhs.derived());
0285 }
0286
0287 private:
0288
0289
0290
0291
0292 subrule& operator=(subrule const&);
0293
0294 template <int ID2, typename ContextT2>
0295 subrule& operator=(subrule<ID2, ContextT2> const&);
0296 };
0297
0298 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
0299
0300 }}
0301
0302 #endif
0303