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   	    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  	
(1) Event cond_true: Condition "this->definitions.size() <= id", taking true branch.
154  	            if (definitions.size()<=id)
155  	                definitions.resize(id*3/2+1);
(2) Event cond_false: Condition "this->definitions[id] != NULL", taking false branch.
156  	            if (definitions[id]!=0)
(3) Event if_end: End of if statement.
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;
(4) Event extract: Calling "get" which extracts wrapped state from local "result".
(5) Event escape: The internal representation of local "result" escapes into "this->definitions[id]", but is destroyed when it exits scope.
168  	            definitions[id] = result.get();
169  	            return *(result.release());
170  	        }
171  	
172  	        int
173  	        undefine(grammar_t* target_grammar)
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  	///////////////////////////////////////////////////////////////////////////////
361  	BOOST_SPIRIT_CLASSIC_NAMESPACE_END
362  	
363  	}} // namespace boost::spirit
364  	
365  	#endif
366