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