• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Copyright (c) 2001-2011 Joel de Guzman
3 
4     Distributed under the Boost Software License, Version 1.0. (See accompanying
5     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 ==============================================================================*/
7 #if !defined(BOOST_SPIRIT_PARSER_BINDER_DECEMBER_05_2008_0516_PM)
8 #define BOOST_SPIRIT_PARSER_BINDER_DECEMBER_05_2008_0516_PM
9 
10 #if defined(_MSC_VER)
11 #pragma once
12 #endif
13 
14 #include <boost/fusion/include/at.hpp>
15 #include <boost/mpl/bool.hpp>
16 #include <boost/spirit/home/support/has_semantic_action.hpp>
17 
18 namespace boost { namespace spirit { namespace qi { namespace detail
19 {
20     // parser_binder for plain rules
21     template <typename Parser, typename Auto>
22     struct parser_binder
23     {
parser_binderboost::spirit::qi::detail::parser_binder24         parser_binder(Parser const& p_)
25           : p(p_) {}
26 
27         template <typename Iterator, typename Skipper, typename Context>
callboost::spirit::qi::detail::parser_binder28         bool call(Iterator& first, Iterator const& last
29           , Context& context, Skipper const& skipper, mpl::true_) const
30         {
31             // If DeducedAuto is false (semantic actions is present), the
32             // component's attribute is unused.
33             return p.parse(first, last, context, skipper, unused);
34         }
35 
36         template <typename Iterator, typename Skipper, typename Context>
callboost::spirit::qi::detail::parser_binder37         bool call(Iterator& first, Iterator const& last
38           , Context& context, Skipper const& skipper, mpl::false_) const
39         {
40             // If DeducedAuto is true (no semantic action), we pass the rule's
41             // attribute on to the component.
42             return p.parse(first, last, context, skipper
43                 , fusion::at_c<0>(context.attributes));
44         }
45 
46         template <typename Iterator, typename Skipper, typename Context>
operator ()boost::spirit::qi::detail::parser_binder47         bool operator()(
48             Iterator& first, Iterator const& last
49           , Context& context, Skipper const& skipper) const
50         {
51             // If Auto is false, we need to deduce whether to apply auto rule
52             typedef typename traits::has_semantic_action<Parser>::type auto_rule;
53             return call(first, last, context, skipper, auto_rule());
54         }
55 
56         Parser p;
57     };
58 
59     // parser_binder for auto rules
60     template <typename Parser>
61     struct parser_binder<Parser, mpl::true_>
62     {
parser_binderboost::spirit::qi::detail::parser_binder63         parser_binder(Parser const& p_)
64           : p(p_) {}
65 
66         template <typename Iterator, typename Skipper, typename Context>
operator ()boost::spirit::qi::detail::parser_binder67         bool operator()(
68             Iterator& first, Iterator const& last
69           , Context& context, Skipper const& skipper) const
70         {
71             // If Auto is true, we pass the rule's attribute on to the component.
72             return p.parse(first, last, context, skipper
73                 , fusion::at_c<0>(context.attributes));
74         }
75 
76         Parser p;
77     };
78 
79     template <typename Auto, typename Parser>
80     inline parser_binder<Parser, Auto>
bind_parser(Parser const & p)81     bind_parser(Parser const& p)
82     {
83         return parser_binder<Parser, Auto>(p);
84     }
85 }}}}
86 
87 #endif
88