1 /*=============================================================================
2 Copyright (c) 2002-2003 Joel de Guzman
3 Copyright (c) 2002-2003 Hartmut Kaiser
4 http://spirit.sourceforge.net/
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
12 ///////////////////////////////////////////////////////////////////////////////
17 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
20 ///////////////////////////////////////////////////////////////////////////
22 // default_parser_context_base class { default context base }
24 ///////////////////////////////////////////////////////////////////////////
25 struct default_parser_context_base
27 template <typename DerivedT>
31 ///////////////////////////////////////////////////////////////////////////
33 // parser_context_base class { base class of all context classes }
35 ///////////////////////////////////////////////////////////////////////////
36 struct parser_context_base {};
38 ///////////////////////////////////////////////////////////////////////////
40 // parser_context class { default context }
42 ///////////////////////////////////////////////////////////////////////////
44 template<typename ContextT> struct parser_context_linker;
46 template<typename AttrT = nil_t>
47 struct parser_context : parser_context_base
50 typedef default_parser_context_base base_t;
51 typedef parser_context_linker<parser_context<AttrT> > context_linker_t;
53 template <typename ParserT>
54 parser_context(ParserT const&) {}
56 template <typename ParserT, typename ScannerT>
58 pre_parse(ParserT const&, ScannerT const&) {}
60 template <typename ResultT, typename ParserT, typename ScannerT>
62 post_parse(ResultT& hit, ParserT const&, ScannerT const&)
66 ///////////////////////////////////////////////////////////////////////////
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).
74 // Basically, this class provides ContextT dependent optional
75 // functionality to the derived class DerivedT through the CRTP
76 // idiom (Curiously recurring template pattern).
78 ///////////////////////////////////////////////////////////////////////////
79 template <typename ContextT, typename DerivedT>
80 struct context_aux : public ContextT::base_t::template aux<DerivedT> {};
82 ///////////////////////////////////////////////////////////////////////////
84 // parser_scanner_linker and parser_scanner_linker classes
85 // { helper templates for the rule extensibility }
87 // This classes can be 'overloaded' (defined elsewhere), to plug
88 // in additional functionality into the non-terminal parsing process.
90 ///////////////////////////////////////////////////////////////////////////
91 #if !defined(BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED)
92 #define BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED
94 template<typename ScannerT>
95 struct parser_scanner_linker : public ScannerT
97 parser_scanner_linker(ScannerT const scan_) : ScannerT(scan_) {}
100 #endif // !defined(BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED)
102 //////////////////////////////////
103 #if !defined(BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED)
104 #define BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED
106 template<typename ContextT>
107 struct parser_context_linker : public ContextT
109 template <typename ParserT>
110 parser_context_linker(ParserT const& p)
113 template <typename ParserT, typename ScannerT>
114 void pre_parse(ParserT const& p, ScannerT const& scan)
115 { ContextT::pre_parse(p, scan); }
117 template <typename ResultT, typename ParserT, typename ScannerT>
119 post_parse(ResultT& hit, ParserT const& p, ScannerT const& scan)
120 { return ContextT::post_parse(hit, p, scan); }
123 #endif // !defined(BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED)
125 ///////////////////////////////////////////////////////////////////////////
127 // BOOST_SPIRIT_CONTEXT_PARSE helper macro
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!
135 // WARNING: INTERNAL USE ONLY. NOT FOR PUBLIC CONSUMPTION.
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);
145 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
147 } // namespace spirit