Back to home page

EIC code displayed by LXR

 
 

    


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     Copyright (c) 2001-2011 Joel de Guzman
0003 
0004     Distributed under the Boost Software License, Version 1.0. (See accompanying
0005     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
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     // Enablers
0038     ///////////////////////////////////////////////////////////////////////////
0039     template <typename Eval>
0040     struct use_terminal<qi::domain, phoenix::actor<Eval> >  // enables phoenix actors
0041         : mpl::true_ {};
0042 
0043     // forward declaration
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& /*attr*/, mpl::true_)
0071         {
0072             // If DeducedAuto is false (semantic actions is present), the
0073             // component's attribute is unused.
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             // If DeducedAuto is true (no semantic action), we pass the parser's
0085             // attribute on to the component.
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             // If you got an error_invalid_expression error message here,
0108             // then the expression (expr_type) is not a valid spirit qi
0109             // expression.
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             // If you got an error_invalid_expression error message here,
0179             // then the expression (expr_type) is not a valid spirit qi
0180             // expression.
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     // Parser generators: make_xxx function (objects)
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