]> git.sesse.net Git - casparcg/blob - dependencies/boost/boost/spirit/home/classic/core/non_terminal/parser_context.hpp
Manually merged pull request #222
[casparcg] / dependencies / boost / boost / spirit / home / classic / core / non_terminal / parser_context.hpp
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     {
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