Line data Source code
1 : /*=============================================================================
2 : Copyright (c) 2001-2003 Joel de Guzman
3 : Copyright (c) 2002-2003 Martin Wille
4 : Copyright (c) 2003 Hartmut Kaiser
5 : http://spirit.sourceforge.net/
6 :
7 : Use, modification and distribution is subject to the Boost Software
8 : License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
9 : http://www.boost.org/LICENSE_1_0.txt)
10 : =============================================================================*/
11 : #if !defined BOOST_SPIRIT_GRAMMAR_IPP
12 : #define BOOST_SPIRIT_GRAMMAR_IPP
13 :
14 : #if !defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE)
15 : #include <boost/spirit/home/classic/core/non_terminal/impl/object_with_id.ipp>
16 : #include <algorithm>
17 : #include <functional>
18 : #include <boost/move/unique_ptr.hpp>
19 : #include <boost/weak_ptr.hpp>
20 : #endif
21 :
22 : #ifdef BOOST_SPIRIT_THREADSAFE
23 : #include <boost/spirit/home/classic/core/non_terminal/impl/static.hpp>
24 : #include <boost/thread/tss.hpp>
25 : #include <boost/thread/mutex.hpp>
26 : #include <boost/thread/lock_types.hpp>
27 : #endif
28 :
29 : ///////////////////////////////////////////////////////////////////////////////
30 : namespace boost { namespace spirit {
31 :
32 : BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
33 :
34 : template <typename DerivedT, typename ContextT>
35 : struct grammar;
36 :
37 :
38 : //////////////////////////////////
39 : template <typename GrammarT, typename ScannerT>
40 : struct grammar_definition
41 : {
42 : typedef typename GrammarT::template definition<ScannerT> type;
43 : };
44 :
45 :
46 : namespace impl
47 : {
48 :
49 : #if !defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE)
50 : struct grammar_tag {};
51 :
52 : //////////////////////////////////
53 : template <typename GrammarT>
54 0 : struct grammar_helper_base
55 : {
56 : virtual int undefine(GrammarT *) = 0;
57 : virtual ~grammar_helper_base() {}
58 : };
59 :
60 : //////////////////////////////////
61 : template <typename GrammarT>
62 : struct grammar_helper_list
63 : {
64 : typedef GrammarT grammar_t;
65 : typedef grammar_helper_base<GrammarT> helper_t;
66 : typedef std::vector<helper_t*> vector_t;
67 :
68 0 : grammar_helper_list() {}
69 : grammar_helper_list(grammar_helper_list const& /*x*/)
70 : { // Does _not_ copy the helpers member !
71 : }
72 :
73 : grammar_helper_list& operator=(grammar_helper_list const& /*x*/)
74 : { // Does _not_ copy the helpers member !
75 : return *this;
76 : }
77 :
78 0 : void push_back(helper_t *helper)
79 0 : { helpers.push_back(helper); }
80 :
81 : void pop_back()
82 : { helpers.pop_back(); }
83 :
84 : typename vector_t::size_type
85 : size() const
86 : { return helpers.size(); }
87 :
88 : typename vector_t::reverse_iterator
89 0 : rbegin()
90 0 : { return helpers.rbegin(); }
91 :
92 : typename vector_t::reverse_iterator
93 0 : rend()
94 0 : { return helpers.rend(); }
95 :
96 : #ifdef BOOST_SPIRIT_THREADSAFE
97 0 : boost::mutex & mutex()
98 0 : { return m; }
99 : #endif
100 :
101 : private:
102 :
103 : vector_t helpers;
104 : #ifdef BOOST_SPIRIT_THREADSAFE
105 : boost::mutex m;
106 : #endif
107 : };
108 :
109 : //////////////////////////////////
110 : struct grammartract_helper_list;
111 :
112 : #if !defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE)
113 :
114 : struct grammartract_helper_list
115 : {
116 : template<typename GrammarT>
117 : static grammar_helper_list<GrammarT>&
118 0 : do_(GrammarT const* g)
119 : {
120 0 : return g->helpers;
121 : }
122 : };
123 :
124 : #endif
125 :
126 : //////////////////////////////////
127 : template <typename GrammarT, typename DerivedT, typename ScannerT>
128 : struct grammar_helper : private grammar_helper_base<GrammarT>
129 : {
130 : typedef GrammarT grammar_t;
131 : typedef ScannerT scanner_t;
132 : typedef DerivedT derived_t;
133 : typedef typename grammar_definition<DerivedT, ScannerT>::type definition_t;
134 :
135 : typedef grammar_helper<grammar_t, derived_t, scanner_t> helper_t;
136 : typedef boost::shared_ptr<helper_t> helper_ptr_t;
137 : typedef boost::weak_ptr<helper_t> helper_weak_ptr_t;
138 :
139 : grammar_helper*
140 0 : this_() { return this; }
141 :
142 0 : grammar_helper(helper_weak_ptr_t& p)
143 : : definitions_cnt(0)
144 0 : , self(this_())
145 0 : { p = self; }
146 :
147 : definition_t&
148 0 : define(grammar_t const* target_grammar)
149 : {
150 : grammar_helper_list<GrammarT> &helpers =
151 0 : grammartract_helper_list::do_(target_grammar);
152 0 : typename grammar_t::object_id id = target_grammar->get_object_id();
153 :
154 0 : if (definitions.size()<=id)
155 0 : definitions.resize(id*3/2+1);
156 0 : if (definitions[id]!=0)
157 0 : return *definitions[id];
158 :
159 : boost::movelib::unique_ptr<definition_t>
160 0 : result(new definition_t(target_grammar->derived()));
161 :
162 : #ifdef BOOST_SPIRIT_THREADSAFE
163 0 : boost::unique_lock<boost::mutex> lock(helpers.mutex());
164 : #endif
165 0 : helpers.push_back(this);
166 :
167 0 : ++definitions_cnt;
168 0 : definitions[id] = result.get();
169 0 : return *(result.release());
170 : }
171 :
172 : int
173 0 : undefine(grammar_t* target_grammar)
174 : {
175 0 : typename grammar_t::object_id id = target_grammar->get_object_id();
176 :
177 0 : if (definitions.size()<=id)
178 : return 0;
179 0 : delete definitions[id];
180 0 : definitions[id] = 0;
181 0 : if (--definitions_cnt==0)
182 0 : self.reset();
183 : return 0;
184 : }
185 :
186 : private:
187 :
188 : std::vector<definition_t*> definitions;
189 : unsigned long definitions_cnt;
190 : helper_ptr_t self;
191 : };
192 :
193 : #endif /* defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE) */
194 :
195 : #ifdef BOOST_SPIRIT_THREADSAFE
196 : class get_definition_static_data_tag
197 : {
198 : template<typename DerivedT, typename ContextT, typename ScannerT>
199 : friend typename DerivedT::template definition<ScannerT> &
200 : get_definition(grammar<DerivedT, ContextT> const* self);
201 :
202 0 : get_definition_static_data_tag() {}
203 : };
204 : #endif
205 :
206 : template<typename DerivedT, typename ContextT, typename ScannerT>
207 : inline typename DerivedT::template definition<ScannerT> &
208 0 : get_definition(grammar<DerivedT, ContextT> const* self)
209 : {
210 : #if defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE)
211 :
212 : typedef typename DerivedT::template definition<ScannerT> definition_t;
213 : static definition_t def(self->derived());
214 : return def;
215 : #else
216 : typedef grammar<DerivedT, ContextT> self_t;
217 : typedef impl::grammar_helper<self_t, DerivedT, ScannerT> helper_t;
218 : typedef typename helper_t::helper_weak_ptr_t ptr_t;
219 :
220 : # ifdef BOOST_SPIRIT_THREADSAFE
221 0 : boost::thread_specific_ptr<ptr_t> & tld_helper
222 : = static_<boost::thread_specific_ptr<ptr_t>,
223 : get_definition_static_data_tag>(get_definition_static_data_tag());
224 :
225 0 : if (!tld_helper.get())
226 0 : tld_helper.reset(new ptr_t);
227 0 : ptr_t &helper = *tld_helper;
228 : # else
229 : static ptr_t helper;
230 : # endif
231 0 : if (helper.expired())
232 0 : new helper_t(helper);
233 0 : return helper.lock()->define(self);
234 : #endif
235 : }
236 :
237 : template <int N>
238 : struct call_helper {
239 :
240 : template <typename RT, typename DefinitionT, typename ScannerT>
241 : static void
242 : do_ (RT &result, DefinitionT &def, ScannerT const &scan)
243 : {
244 : result = def.template get_start_parser<N>()->parse(scan);
245 : }
246 : };
247 :
248 : template <>
249 : struct call_helper<0> {
250 :
251 : template <typename RT, typename DefinitionT, typename ScannerT>
252 : static void
253 0 : do_ (RT &result, DefinitionT &def, ScannerT const &scan)
254 : {
255 0 : result = def.start().parse(scan);
256 : }
257 : };
258 :
259 : //////////////////////////////////
260 : template<int N, typename DerivedT, typename ContextT, typename ScannerT>
261 : inline typename parser_result<grammar<DerivedT, ContextT>, ScannerT>::type
262 0 : grammar_parser_parse(
263 : grammar<DerivedT, ContextT> const* self,
264 : ScannerT const &scan)
265 : {
266 : typedef
267 : typename parser_result<grammar<DerivedT, ContextT>, ScannerT>::type
268 : result_t;
269 : typedef typename DerivedT::template definition<ScannerT> definition_t;
270 :
271 0 : result_t result;
272 0 : definition_t &def = get_definition<DerivedT, ContextT, ScannerT>(self);
273 :
274 0 : call_helper<N>::do_(result, def, scan);
275 0 : return result;
276 : }
277 :
278 : //////////////////////////////////
279 : template<typename GrammarT>
280 : inline void
281 0 : grammar_destruct(GrammarT* self)
282 : {
283 : #if !defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE)
284 : typedef grammar_helper_list<GrammarT> helper_list_t;
285 :
286 : helper_list_t& helpers =
287 0 : grammartract_helper_list::do_(self);
288 :
289 : typedef typename helper_list_t::vector_t::reverse_iterator iterator_t;
290 :
291 0 : for (iterator_t i = helpers.rbegin(); i != helpers.rend(); ++i)
292 0 : (*i)->undefine(self);
293 : #else
294 : (void)self;
295 : #endif
296 : }
297 :
298 : ///////////////////////////////////////////////////////////////////////////
299 : //
300 : // entry_grammar class
301 : //
302 : ///////////////////////////////////////////////////////////////////////////
303 : template <typename DerivedT, int N, typename ContextT>
304 : class entry_grammar
305 : : public parser<entry_grammar<DerivedT, N, ContextT> >
306 : {
307 :
308 : public:
309 : typedef entry_grammar<DerivedT, N, ContextT> self_t;
310 : typedef self_t embed_t;
311 : typedef typename ContextT::context_linker_t context_t;
312 : typedef typename context_t::attr_t attr_t;
313 :
314 : template <typename ScannerT>
315 : struct result
316 : {
317 : typedef typename match_result<ScannerT, attr_t>::type type;
318 : };
319 :
320 : entry_grammar(DerivedT const &p) : target_grammar(p) {}
321 :
322 : template <typename ScannerT>
323 : typename parser_result<self_t, ScannerT>::type
324 : parse_main(ScannerT const& scan) const
325 : { return impl::grammar_parser_parse<N>(&target_grammar, scan); }
326 :
327 : template <typename ScannerT>
328 : typename parser_result<self_t, ScannerT>::type
329 : parse(ScannerT const& scan) const
330 : {
331 : typedef typename parser_result<self_t, ScannerT>::type result_t;
332 : typedef parser_scanner_linker<ScannerT> scanner_t;
333 : BOOST_SPIRIT_CONTEXT_PARSE(scan, target_grammar, scanner_t,
334 : context_t, result_t)
335 : }
336 :
337 : private:
338 : DerivedT const &target_grammar;
339 : };
340 :
341 : } // namespace impl
342 :
343 : ///////////////////////////////////////
344 : #if !defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE)
345 : #define BOOST_SPIRIT_GRAMMAR_ID , public impl::object_with_id<impl::grammar_tag>
346 : #else
347 : #define BOOST_SPIRIT_GRAMMAR_ID
348 : #endif
349 :
350 : ///////////////////////////////////////
351 : #if !defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE)
352 : #define BOOST_SPIRIT_GRAMMAR_STATE \
353 : private: \
354 : friend struct impl::grammartract_helper_list; \
355 : mutable impl::grammar_helper_list<self_t> helpers;
356 : #else
357 : #define BOOST_SPIRIT_GRAMMAR_STATE
358 : #endif
359 :
360 : ///////////////////////////////////////////////////////////////////////////////
361 : BOOST_SPIRIT_CLASSIC_NAMESPACE_END
362 :
363 : }} // namespace boost::spirit
364 :
365 : #endif
|