source: NonGTP/Boost/boost/spirit/core/non_terminal/parser_context.hpp @ 857

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