Warning, file /include/boost/spirit/home/qi/auxiliary/lazy.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007 #if !defined(BOOST_SPIRIT_LAZY_MARCH_27_2007_1002AM)
0008 #define BOOST_SPIRIT_LAZY_MARCH_27_2007_1002AM
0009
0010 #if defined(_MSC_VER)
0011 #pragma once
0012 #endif
0013
0014 #include <boost/spirit/home/qi/domain.hpp>
0015 #include <boost/spirit/home/qi/skip_over.hpp>
0016 #include <boost/spirit/home/qi/meta_compiler.hpp>
0017 #include <boost/spirit/home/qi/detail/attributes.hpp>
0018 #include <boost/spirit/home/support/unused.hpp>
0019 #include <boost/spirit/home/support/info.hpp>
0020 #include <boost/spirit/home/support/lazy.hpp>
0021 #include <boost/fusion/include/at.hpp>
0022 #include <boost/utility/result_of.hpp>
0023 #include <boost/proto/make_expr.hpp>
0024 #include <boost/proto/tags.hpp>
0025 #include <boost/type_traits/remove_reference.hpp>
0026 #include <boost/mpl/not.hpp>
0027
0028 namespace boost { namespace phoenix
0029 {
0030 template <typename Expr>
0031 struct actor;
0032 }}
0033
0034 namespace boost { namespace spirit
0035 {
0036
0037
0038
0039 template <typename Eval>
0040 struct use_terminal<qi::domain, phoenix::actor<Eval> >
0041 : mpl::true_ {};
0042
0043
0044 template <typename Terminal, typename Actor, int Arity>
0045 struct lazy_terminal;
0046 }}
0047
0048 namespace boost { namespace spirit { namespace qi
0049 {
0050 using spirit::lazy;
0051 typedef modify<qi::domain> qi_modify;
0052
0053 namespace detail
0054 {
0055 template <typename Parser, typename Iterator, typename Context
0056 , typename Skipper, typename Attribute>
0057 bool lazy_parse_impl(Parser const& p
0058 , Iterator& first, Iterator const& last
0059 , Context& context, Skipper const& skipper
0060 , Attribute& attr, mpl::false_)
0061 {
0062 return p.parse(first, last, context, skipper, attr);
0063 }
0064
0065 template <typename Parser, typename Iterator, typename Context
0066 , typename Skipper, typename Attribute>
0067 bool lazy_parse_impl(Parser const& p
0068 , Iterator& first, Iterator const& last
0069 , Context& context, Skipper const& skipper
0070 , Attribute& , mpl::true_)
0071 {
0072
0073
0074 return p.parse(first, last, context, skipper, unused);
0075 }
0076
0077 template <typename Parser, typename Iterator, typename Context
0078 , typename Skipper, typename Attribute>
0079 bool lazy_parse_impl_main(Parser const& p
0080 , Iterator& first, Iterator const& last
0081 , Context& context, Skipper const& skipper
0082 , Attribute& attr)
0083 {
0084
0085
0086 typedef typename traits::has_semantic_action<Parser>::type auto_rule;
0087 return lazy_parse_impl(p, first, last, context, skipper, attr, auto_rule());
0088 }
0089 }
0090
0091 template <typename Function, typename Modifiers>
0092 struct lazy_parser : parser<lazy_parser<Function, Modifiers> >
0093 {
0094 template <typename Context, typename Iterator>
0095 struct attribute
0096 {
0097 typedef typename
0098 boost::result_of<qi_modify(tag::lazy_eval, Modifiers)>::type
0099 modifier;
0100
0101 typedef typename
0102 remove_reference<
0103 typename boost::result_of<Function(unused_type, Context)>::type
0104 >::type
0105 expr_type;
0106
0107
0108
0109
0110 BOOST_SPIRIT_ASSERT_MATCH(qi::domain, expr_type);
0111
0112 typedef typename
0113 result_of::compile<qi::domain, expr_type, modifier>::type
0114 parser_type;
0115
0116 typedef typename
0117 traits::attribute_of<parser_type, Context, Iterator>::type
0118 type;
0119 };
0120
0121 lazy_parser(Function const& function_, Modifiers const& modifiers_)
0122 : function(function_), modifiers(modifiers_) {}
0123
0124 template <typename Iterator, typename Context
0125 , typename Skipper, typename Attribute>
0126 bool parse(Iterator& first, Iterator const& last
0127 , Context& context, Skipper const& skipper
0128 , Attribute& attr) const
0129 {
0130 return detail::lazy_parse_impl_main(
0131 compile<qi::domain>(function(unused, context)
0132 , qi_modify()(tag::lazy_eval(), modifiers))
0133 , first, last, context, skipper, attr);
0134 }
0135
0136 template <typename Context>
0137 info what(Context& context) const
0138 {
0139 return info("lazy"
0140 , compile<qi::domain>(function(unused, context)
0141 , qi_modify()(tag::lazy_eval(), modifiers))
0142 .what(context)
0143 );
0144 }
0145
0146 Function function;
0147 Modifiers modifiers;
0148 };
0149
0150
0151 template <typename Function, typename Subject, typename Modifiers>
0152 struct lazy_directive
0153 : unary_parser<lazy_directive<Function, Subject, Modifiers> >
0154 {
0155 typedef Subject subject_type;
0156
0157 template <typename Context, typename Iterator>
0158 struct attribute
0159 {
0160 typedef typename
0161 boost::result_of<qi_modify(tag::lazy_eval, Modifiers)>::type
0162 modifier;
0163
0164 typedef typename
0165 remove_reference<
0166 typename boost::result_of<Function(unused_type, Context)>::type
0167 >::type
0168 directive_expr_type;
0169
0170 typedef typename
0171 proto::result_of::make_expr<
0172 proto::tag::subscript
0173 , directive_expr_type
0174 , Subject
0175 >::type
0176 expr_type;
0177
0178
0179
0180
0181 BOOST_SPIRIT_ASSERT_MATCH(qi::domain, expr_type);
0182
0183 typedef typename
0184 result_of::compile<qi::domain, expr_type, modifier>::type
0185 parser_type;
0186
0187 typedef typename
0188 traits::attribute_of<parser_type, Context, Iterator>::type
0189 type;
0190 };
0191
0192 lazy_directive(
0193 Function const& function_
0194 , Subject const& subject_
0195 , Modifiers const& modifiers_)
0196 : function(function_), subject(subject_), modifiers(modifiers_) {}
0197
0198 template <typename Iterator, typename Context
0199 , typename Skipper, typename Attribute>
0200 bool parse(Iterator& first, Iterator const& last
0201 , Context& context, Skipper const& skipper
0202 , Attribute& attr) const
0203 {
0204 return detail::lazy_parse_impl_main(compile<qi::domain>(
0205 proto::make_expr<proto::tag::subscript>(
0206 function(unused, context)
0207 , subject)
0208 , qi_modify()(tag::lazy_eval(), modifiers))
0209 , first, last, context, skipper, attr);
0210 }
0211
0212 template <typename Context>
0213 info what(Context& context) const
0214 {
0215 return info("lazy-directive"
0216 , compile<qi::domain>(
0217 proto::make_expr<proto::tag::subscript>(
0218 function(unused, context)
0219 , subject
0220 ), qi_modify()(tag::lazy_eval(), modifiers))
0221 .what(context)
0222 );
0223 }
0224
0225 Function function;
0226 Subject subject;
0227 Modifiers modifiers;
0228 };
0229
0230
0231
0232
0233 template <typename Eval, typename Modifiers>
0234 struct make_primitive<phoenix::actor<Eval>, Modifiers>
0235 {
0236 typedef lazy_parser<phoenix::actor<Eval>, Modifiers> result_type;
0237 result_type operator()(phoenix::actor<Eval> const& f
0238 , Modifiers const& modifiers) const
0239 {
0240 return result_type(f, modifiers);
0241 }
0242 };
0243
0244 template <typename Terminal, typename Actor, int Arity, typename Modifiers>
0245 struct make_primitive<lazy_terminal<Terminal, Actor, Arity>, Modifiers>
0246 {
0247 typedef lazy_parser<Actor, Modifiers> result_type;
0248 result_type operator()(
0249 lazy_terminal<Terminal, Actor, Arity> const& lt
0250 , Modifiers const& modifiers) const
0251 {
0252 return result_type(lt.actor, modifiers);
0253 }
0254 };
0255
0256 template <typename Terminal, typename Actor, int Arity, typename Subject, typename Modifiers>
0257 struct make_directive<lazy_terminal<Terminal, Actor, Arity>, Subject, Modifiers>
0258 {
0259 typedef lazy_directive<Actor, Subject, Modifiers> result_type;
0260 result_type operator()(
0261 lazy_terminal<Terminal, Actor, Arity> const& lt
0262 , Subject const& subject, Modifiers const& modifiers) const
0263 {
0264 return result_type(lt.actor, subject, modifiers);
0265 }
0266 };
0267 }}}
0268
0269 namespace boost { namespace spirit { namespace traits
0270 {
0271
0272 template <typename Actor, typename Modifiers, typename Attribute
0273 , typename Context, typename Iterator>
0274 struct handles_container<
0275 qi::lazy_parser<Actor, Modifiers>, Attribute, Context, Iterator>
0276 : handles_container<
0277 typename qi::lazy_parser<Actor, Modifiers>::template
0278 attribute<Context, Iterator>::parser_type
0279 , Attribute, Context, Iterator>
0280 {};
0281
0282 template <typename Subject, typename Actor, typename Modifiers
0283 , typename Attribute, typename Context, typename Iterator>
0284 struct handles_container<
0285 qi::lazy_directive<Actor, Subject, Modifiers>, Attribute
0286 , Context, Iterator>
0287 : handles_container<
0288 typename qi::lazy_directive<Actor, Subject, Modifiers>::template
0289 attribute<Context, Iterator>::parser_type
0290 , Attribute, Context, Iterator>
0291 {};
0292 }}}
0293
0294 #endif