source: NonGTP/Boost/boost/spirit/core/non_terminal/impl/grammar.ipp @ 857

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