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 | ///////////////////////////////////////////////////////////////////////////////
|
---|
14 | namespace 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
|
---|