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///////////////////////////////////////////////////////////////////////////////
30namespace boost { namespace spirit {
31
32BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
33
34template <typename DerivedT, typename ContextT>
35struct grammar;
36
37
38//////////////////////////////////
39template <typename GrammarT, typename ScannerT>
40struct 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    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        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        void push_back(helper_t *helper)
79        { 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        rbegin()
90        { return helpers.rbegin(); }
91
92        typename vector_t::reverse_iterator
93        rend()
94        { return helpers.rend(); }
95
96#ifdef BOOST_SPIRIT_THREADSAFE
97        boost::mutex & mutex()
98        { 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        do_(GrammarT const* g)
119        {
120            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        this_() { return this; }
141
142        grammar_helper(helper_weak_ptr_t& p)
143        : definitions_cnt(0)
144        , self(this_())
145        { p = self; }
146
147        definition_t&
148        define(grammar_t const* target_grammar)
149        {
150            grammar_helper_list<GrammarT> &helpers =
151            grammartract_helper_list::do_(target_grammar);
152            typename grammar_t::object_id id = target_grammar->get_object_id();
153
154            if (definitions.size()<=id)
155                definitions.resize(id*3/2+1);
156            if (definitions[id]!=0)
157                return *definitions[id];
158
159            boost::movelib::unique_ptr<definition_t>
160                result(new definition_t(target_grammar->derived()));
161
162#ifdef BOOST_SPIRIT_THREADSAFE
163            boost::unique_lock<boost::mutex> lock(helpers.mutex());
164#endif
165            helpers.push_back(this);
166
167            ++definitions_cnt;
168            definitions[id] = result.get();
169            return *(result.release());
170        }
171
172        int
173        undefine(grammar_t* target_grammar) BOOST_OVERRIDE
174        {
175            typename grammar_t::object_id id = target_grammar->get_object_id();
176
177            if (definitions.size()<=id)
178                return 0;
179            delete definitions[id];
180            definitions[id] = 0;
181            if (--definitions_cnt==0)
182                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        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    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        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        if (!tld_helper.get())
226            tld_helper.reset(new ptr_t);
227        ptr_t &helper = *tld_helper;
228# else
229        static ptr_t helper;
230# endif
231        if (helper.expired())
232            new helper_t(helper);
233        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        do_ (RT &result, DefinitionT &def, ScannerT const &scan)
254        {
255            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    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        result_t result;
272        definition_t &def = get_definition<DerivedT, ContextT, ScannerT>(self);
273
274        call_helper<N>::do_(result, def, scan);
275        return result;
276    }
277
278    //////////////////////////////////
279    template<typename GrammarT>
280    inline void
281    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        grammartract_helper_list::do_(self);
288
289        typedef typename helper_list_t::vector_t::reverse_iterator iterator_t;
290
291        for (iterator_t i = helpers.rbegin(); i != helpers.rend(); ++i)
292            (*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///////////////////////////////////////////////////////////////////////////////
361BOOST_SPIRIT_CLASSIC_NAMESPACE_END
362
363}} // namespace boost::spirit
364
365#endif
366