diff DEPENDENCIES/generic/include/boost/spirit/home/x3/nonterminal/detail/rule.hpp @ 102:f46d142149f5

Whoops, finish that update
author Chris Cannam
date Mon, 07 Sep 2015 11:13:41 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DEPENDENCIES/generic/include/boost/spirit/home/x3/nonterminal/detail/rule.hpp	Mon Sep 07 11:13:41 2015 +0100
@@ -0,0 +1,385 @@
+/*=============================================================================
+    Copyright (c) 2001-2014 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_X3_DETAIL_RULE_JAN_08_2012_0326PM)
+#define BOOST_SPIRIT_X3_DETAIL_RULE_JAN_08_2012_0326PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/core/parser.hpp>
+#include <boost/spirit/home/x3/support/traits/make_attribute.hpp>
+#include <boost/spirit/home/x3/support/utility/sfinae.hpp>
+#include <boost/spirit/home/x3/nonterminal/detail/transform_attribute.hpp>
+#include <boost/utility/addressof.hpp>
+
+#if defined(BOOST_SPIRIT_X3_DEBUG)
+#include <boost/spirit/home/x3/nonterminal/simple_trace.hpp>
+#endif
+
+namespace boost { namespace spirit { namespace x3
+{
+    template <typename ID>
+    struct identity;
+    
+    template <typename ID, typename Attribute = unused_type>
+    struct rule;
+
+    struct parse_pass_context_tag;
+
+    namespace detail
+    {
+        // we use this so we can detect if the default parse_rule
+        // is the being called.
+        struct default_parse_rule_result
+        {
+            default_parse_rule_result(bool r)
+              : r(r) {}
+            operator bool() const { return r; }
+            bool r;
+        };
+    }
+    
+    // default parse_rule implementation
+    template <typename ID, typename Attribute, typename Iterator
+      , typename Context, typename ActualAttribute>
+    inline detail::default_parse_rule_result
+    parse_rule(
+        rule<ID, Attribute> rule_
+      , Iterator& first, Iterator const& last
+      , Context const& context, ActualAttribute& attr);
+}}}
+
+namespace boost { namespace spirit { namespace x3 { namespace detail
+{
+#if defined(BOOST_SPIRIT_X3_DEBUG)
+    template <typename Iterator, typename Attribute>
+    struct context_debug
+    {
+        context_debug(
+            char const* rule_name
+          , Iterator const& first, Iterator const& last
+          , Attribute const& attr
+          , bool const& ok_parse //was parse successful?
+          )
+          : ok_parse(ok_parse), rule_name(rule_name)
+          , first(first), last(last)
+          , attr(attr)
+          , f(detail::get_simple_trace())
+        {
+            f(first, last, attr, pre_parse, rule_name);
+        }
+
+        ~context_debug()
+        {
+            auto status = ok_parse ? successful_parse : failed_parse ;
+            f(first, last, attr, status, rule_name);
+        }
+
+        bool const& ok_parse;
+        char const* rule_name;
+        Iterator const& first;
+        Iterator const& last;
+        Attribute const& attr;
+        detail::simple_trace_type& f;
+    };
+#endif
+    
+    template <typename ID, typename Iterator, typename Context, typename Enable = void>
+    struct has_on_error : mpl::false_ {};
+
+    template <typename ID, typename Iterator, typename Context>
+    struct has_on_error<ID, Iterator, Context,
+        typename disable_if_substitution_failure<
+            decltype(
+                std::declval<ID>().on_error(
+                    std::declval<Iterator&>()
+                  , std::declval<Iterator>()
+                  , std::declval<expectation_failure<Iterator>>()
+                  , std::declval<Context>()
+                )
+            )>::type
+        >
+      : mpl::true_
+    {};
+    
+    template <typename ID, typename Iterator, typename Attribute, typename Context, typename Enable = void>
+    struct has_on_success : mpl::false_ {};
+
+    template <typename ID, typename Iterator, typename Attribute, typename Context>
+    struct has_on_success<ID, Iterator, Context, Attribute,
+        typename disable_if_substitution_failure<
+            decltype(
+                std::declval<ID>().on_success(
+                    std::declval<Iterator&>()
+                  , std::declval<Iterator>()
+                  , std::declval<Attribute&>()
+                  , std::declval<Context>()
+                )
+            )>::type
+        >
+      : mpl::true_
+    {};
+
+    template <typename ID>
+    struct make_id
+    {
+        typedef identity<ID> type;
+    };
+
+    template <typename ID>
+    struct make_id<identity<ID>>
+    {
+        typedef identity<ID> type;
+    };
+    
+    template <typename ID, typename RHS, typename Context>
+    Context const&
+    make_rule_context(RHS const& rhs, Context const& context
+      , mpl::false_ /* is_default_parse_rule */)
+    {
+        return context;
+    }
+    
+    template <typename ID, typename RHS, typename Context>
+    auto make_rule_context(RHS const& rhs, Context const& context
+      , mpl::true_ /* is_default_parse_rule */ )
+    {
+        return make_unique_context<ID>(rhs, context);
+    }
+
+    template <typename Attribute, typename ID>
+    struct rule_parser
+    {
+        template <typename Iterator, typename Context, typename ActualAttribute>
+        static bool call_on_success(
+            Iterator& first, Iterator const& last
+          , Context const& context, ActualAttribute& attr
+          , mpl::false_ /* No on_success handler */ )
+        {
+            return true;
+        }
+        
+        template <typename Iterator, typename Context, typename ActualAttribute>
+        static bool call_on_success(
+            Iterator& first, Iterator const& last
+          , Context const& context, ActualAttribute& attr
+          , mpl::true_ /* Has on_success handler */)
+        {
+            bool pass = true;
+            ID().on_success(
+                first
+              , last
+              , attr
+              , make_context<parse_pass_context_tag>(pass, context)
+            );
+            return pass;
+        }
+        
+        template <typename RHS, typename Iterator, typename Context
+          , typename RContext, typename ActualAttribute>
+        static bool parse_rhs_main(
+            RHS const& rhs
+          , Iterator& first, Iterator const& last
+          , Context const& context, RContext& rcontext, ActualAttribute& attr
+          , mpl::false_)
+        {
+            // see if the user has a BOOST_SPIRIT_DEFINE for this rule
+            typedef
+                decltype(parse_rule(
+                    rule<ID, Attribute>(), first, last
+                  , make_unique_context<ID>(rhs, context), attr))
+            parse_rule_result;
+
+            // If there is no BOOST_SPIRIT_DEFINE for this rule,
+            // we'll make a context for this rule tagged by its ID
+            // so we can extract the rule later on in the default
+            // (generic) parse_rule function.
+            typedef
+                is_same<parse_rule_result, default_parse_rule_result>
+            is_default_parse_rule;
+
+            Iterator i = first;
+            bool r = rhs.parse(
+                i
+              , last
+              , make_rule_context<ID>(rhs, context, is_default_parse_rule())
+              , rcontext
+              , attr
+            );
+
+            if (r)
+            {
+                auto first_ = first;
+                x3::skip_over(first_, last, context);
+                r = call_on_success(first_, i, context, attr
+                  , has_on_success<ID, Iterator, Context, ActualAttribute>());
+            }
+            
+            if (r)
+                first = i;
+            return r;
+        }
+
+        template <typename RHS, typename Iterator, typename Context
+          , typename RContext, typename ActualAttribute>
+        static bool parse_rhs_main(
+            RHS const& rhs
+          , Iterator& first, Iterator const& last
+          , Context const& context, RContext& rcontext, ActualAttribute& attr
+          , mpl::true_ /* on_error is found */)
+        {
+            for (;;)
+            {
+                try
+                {
+                    return parse_rhs_main(
+                        rhs, first, last, context, rcontext, attr, mpl::false_());
+                }
+                catch (expectation_failure<Iterator> const& x)
+                {
+                    switch (ID().on_error(first, last, x, context))
+                    {
+                        case error_handler_result::fail:
+                            return false;
+                        case error_handler_result::retry:
+                            continue;
+                        case error_handler_result::accept:
+                            return true;
+                        case error_handler_result::rethrow:
+                            throw;
+                    }
+                }
+            }
+        }
+
+        template <typename RHS, typename Iterator
+          , typename Context, typename RContext, typename ActualAttribute>
+        static bool parse_rhs_main(
+            RHS const& rhs
+          , Iterator& first, Iterator const& last
+          , Context const& context, RContext& rcontext, ActualAttribute& attr)
+        {
+            return parse_rhs_main(
+                rhs, first, last, context, rcontext, attr
+              , has_on_error<ID, Iterator, Context>()
+            );
+        }
+
+        template <typename RHS, typename Iterator
+          , typename Context, typename RContext, typename ActualAttribute>
+        static bool parse_rhs(
+            RHS const& rhs
+          , Iterator& first, Iterator const& last
+          , Context const& context, RContext& rcontext, ActualAttribute& attr
+          , mpl::false_)
+        {
+            return parse_rhs_main(rhs, first, last, context, rcontext, attr);
+        }
+
+        template <typename RHS, typename Iterator
+          , typename Context, typename RContext, typename ActualAttribute>
+        static bool parse_rhs(
+            RHS const& rhs
+          , Iterator& first, Iterator const& last
+          , Context const& context, RContext& rcontext, ActualAttribute& attr
+          , mpl::true_)
+        {
+            return parse_rhs_main(rhs, first, last, context, rcontext, unused);
+        }
+
+        template <typename RHS, typename Iterator, typename Context
+          , typename ActualAttribute, typename ExplicitAttrPropagation>
+        static bool call_rule_definition(
+            RHS const& rhs
+          , char const* rule_name
+          , Iterator& first, Iterator const& last
+          , Context const& context, ActualAttribute& attr
+          , ExplicitAttrPropagation)
+        {
+            typedef traits::make_attribute<Attribute, ActualAttribute> make_attribute;
+
+            // do down-stream transformation, provides attribute for
+            // rhs parser
+            typedef traits::transform_attribute<
+                typename make_attribute::type, Attribute, parser_id>
+            transform;
+
+            typedef typename make_attribute::value_type value_type;
+            typedef typename transform::type transform_attr;
+            value_type made_attr = make_attribute::call(attr);
+            transform_attr attr_ = transform::pre(made_attr);
+
+            bool ok_parse
+              //Creates a place to hold the result of parse_rhs
+              //called inside the following scope.
+              ;
+            {
+             //Create a scope to cause the dbg variable below (within
+             //the #if...#endif) to call it's DTOR before any
+             //modifications are made to the attribute, attr_ passed
+             //to parse_rhs (such as might be done in
+             //traits::post_transform when, for example,
+             //ActualAttribute is a recursive variant).
+#if defined(BOOST_SPIRIT_X3_DEBUG)
+                  context_debug<Iterator, typename make_attribute::value_type>
+                dbg(rule_name, first, last, attr_, ok_parse);
+#endif
+                ok_parse=parse_rhs(rhs, first, last, context, attr_, attr_
+                   , mpl::bool_
+                     < (  RHS::has_action 
+                       && !ExplicitAttrPropagation::value
+                       )
+                     >()
+                  );
+            }
+            if(ok_parse)
+            {
+                // do up-stream transformation, this integrates the results
+                // back into the original attribute value, if appropriate
+                traits::post_transform(attr, attr_);
+            }
+            return ok_parse;
+        }
+
+//        template <typename RuleDef, typename Iterator, typename Context
+//            , typename ActualAttribute, typename AttributeContext>
+//        static bool call_from_rule(
+//            RuleDef const& rule_def
+//          , char const* rule_name
+//          , Iterator& first, Iterator const& last
+//          , Context const& context, ActualAttribute& attr, AttributeContext& attr_ctx)
+//        {
+//            // This is called when a rule-body has already been established.
+//            // The rule body is already established by the rule_definition class,
+//            // we will not do it again. We'll simply call the RHS by calling
+//            // call_rule_definition.
+//
+//            return call_rule_definition(
+//                rule_def.rhs, rule_name, first, last
+//              , context, attr, attr_ctx.attr_ptr
+//              , mpl::bool_<(RuleDef::explicit_attribute_propagation)>());
+//        }
+//
+//        template <typename RuleDef, typename Iterator, typename Context
+//            , typename ActualAttribute>
+//        static bool call_from_rule(
+//            RuleDef const& rule_def
+//          , char const* rule_name
+//          , Iterator& first, Iterator const& last
+//          , Context const& context, ActualAttribute& attr, unused_type)
+//        {
+//            // This is called when a rule-body has *not yet* been established.
+//            // The rule body is established by the rule_definition class, so
+//            // we call it to parse and establish the rule-body.
+//
+//            return rule_def.parse(first, last, context, unused, attr); // $$$ fix unused param $$$
+//        }
+    };
+}}}}
+
+#endif