1    	/*=============================================================================
2    	    Copyright (c) 2002-2003 Joel de Guzman
3    	    Copyright (c) 2002-2003 Hartmut Kaiser
4    	    http://spirit.sourceforge.net/
5    	
6    	  Distributed under the Boost Software License, Version 1.0. (See accompanying
7    	  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8    	=============================================================================*/
9    	#if !defined(BOOST_SPIRIT_PARSER_CONTEXT_HPP)
10   	#define BOOST_SPIRIT_PARSER_CONTEXT_HPP
11   	
12   	///////////////////////////////////////////////////////////////////////////////
13   	namespace boost
14   	{
15   	    namespace spirit
16   	    {
17   	    BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
18   	
19   	
20   	    ///////////////////////////////////////////////////////////////////////////
21   	    //
22   	    //  default_parser_context_base class { default context base }
23   	    //
24   	    ///////////////////////////////////////////////////////////////////////////
25   	    struct default_parser_context_base
26   	    {
27   	        template <typename DerivedT>
28   	        struct aux {};
29   	    };
30   	
31   	    ///////////////////////////////////////////////////////////////////////////
32   	    //
33   	    //  parser_context_base class { base class of all context classes }
34   	    //
35   	    ///////////////////////////////////////////////////////////////////////////
36   	    struct parser_context_base {};
37   	
38   	    ///////////////////////////////////////////////////////////////////////////
39   	    //
40   	    //  parser_context class { default context }
41   	    //
42   	    ///////////////////////////////////////////////////////////////////////////
43   	    struct nil_t;
44   	    template<typename ContextT> struct parser_context_linker;
45   	
46   	    template<typename AttrT = nil_t>
47   	    struct parser_context : parser_context_base
48   	    {
49   	        typedef AttrT attr_t;
50   	        typedef default_parser_context_base base_t;
51   	        typedef parser_context_linker<parser_context<AttrT> > context_linker_t;
52   	
53   	        template <typename ParserT>
54   	        parser_context(ParserT const&) {}
55   	
56   	        template <typename ParserT, typename ScannerT>
57   	        void
58   	        pre_parse(ParserT const&, ScannerT const&) {}
59   	
60   	        template <typename ResultT, typename ParserT, typename ScannerT>
61   	        ResultT&
62   	        post_parse(ResultT& hit, ParserT const&, ScannerT const&)
63   	        { return hit; }
64   	    };
65   	
66   	    ///////////////////////////////////////////////////////////////////////////
67   	    //
68   	    //  context_aux class
69   	    //
70   	    //      context_aux<ContextT, DerivedT> is a class derived from the
71   	    //      ContextT's nested base_t::base<DerivedT> template class. (see
72   	    //      default_parser_context_base::aux for an example).
73   	    //
74   	    //      Basically, this class provides ContextT dependent optional
75   	    //      functionality to the derived class DerivedT through the CRTP
76   	    //      idiom (Curiously recurring template pattern).
77   	    //
78   	    ///////////////////////////////////////////////////////////////////////////
79   	    template <typename ContextT, typename DerivedT>
80   	    struct context_aux : public ContextT::base_t::template aux<DerivedT> {};
81   	
82   	    ///////////////////////////////////////////////////////////////////////////
83   	    //
84   	    //  parser_scanner_linker and parser_scanner_linker classes
85   	    //  { helper templates for the rule extensibility }
86   	    //
87   	    //      This classes can be 'overloaded' (defined elsewhere), to plug
88   	    //      in additional functionality into the non-terminal parsing process.
89   	    //
90   	    ///////////////////////////////////////////////////////////////////////////
91   	    #if !defined(BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED)
92   	    #define BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED
93   	
94   	    template<typename ScannerT>
95   	    struct parser_scanner_linker : public ScannerT
96   	    {
(1) Event pass_by_value: Passing parameter scan_ of type "boost::spirit::classic::scanner<boost::spirit::classic::position_iterator<boost::spirit::classic::multi_pass<std::istream_iterator<char, char, std::char_traits<char>, long>, boost::spirit::classic::multi_pass_policies::input_iterator, boost::spirit::classic::multi_pass_policies::ref_counted, boost::spirit::classic::multi_pass_policies::buf_id_check, boost::spirit::classic::multi_pass_policies::std_deque>, boost::spirit::classic::file_position_base<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::spirit::classic::nil_t>, boost::spirit::classic::scanner_policies<boost::spirit::classic::skipper_iteration_policy<boost::spirit::classic::iteration_policy>, boost::spirit::classic::match_policy, boost::spirit::classic::action_policy> > const" (size 160 bytes) by value.
97   	        parser_scanner_linker(ScannerT const scan_) : ScannerT(scan_) {}
98   	    };
99   	
100  	    #endif // !defined(BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED)
101  	
102  	    //////////////////////////////////
103  	    #if !defined(BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED)
104  	    #define BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED
105  	
106  	    template<typename ContextT>
107  	    struct parser_context_linker : public ContextT
108  	    {
109  	        template <typename ParserT>
110  	        parser_context_linker(ParserT const& p)
111  	        : ContextT(p) {}
112  	
113  	        template <typename ParserT, typename ScannerT>
114  	        void pre_parse(ParserT const& p, ScannerT const& scan)
115  	        { ContextT::pre_parse(p, scan); }
116  	
117  	        template <typename ResultT, typename ParserT, typename ScannerT>
118  	        ResultT&
119  	        post_parse(ResultT& hit, ParserT const& p, ScannerT const& scan)
120  	        { return ContextT::post_parse(hit, p, scan); }
121  	    };
122  	
123  	    #endif // !defined(BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED)
124  	
125  	    ///////////////////////////////////////////////////////////////////////////
126  	    //
127  	    //  BOOST_SPIRIT_CONTEXT_PARSE helper macro
128  	    //
129  	    //      The original implementation uses a template class. However, we
130  	    //      need to lessen the template instantiation depth to help inferior
131  	    //      compilers that sometimes choke on deep template instantiations.
132  	    //      The objective is to avoid code redundancy. A macro, in this case
133  	    //      is an obvious solution. Sigh!
134  	    //
135  	    //      WARNING: INTERNAL USE ONLY. NOT FOR PUBLIC CONSUMPTION.
136  	    //
137  	    ///////////////////////////////////////////////////////////////////////////
138  	    #define BOOST_SPIRIT_CONTEXT_PARSE(scan, this_, scanner_t, context_t, result_t) \
139  	            scanner_t scan_wrap(scan);                                              \
140  	            context_t context_wrap(this_);                                          \
141  	            context_wrap.pre_parse(this_, scan_wrap);                               \
142  	            result_t hit = parse_main(scan);                                        \
143  	            return context_wrap.post_parse(hit, this_, scan_wrap);
144  	
145  	    BOOST_SPIRIT_CLASSIC_NAMESPACE_END
146  	
147  	    } // namespace spirit
148  	} // namespace boost
149  	
150  	#endif
151