374 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			374 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|   | /*============================================================================= | ||
|  |     Copyright (c) 2001-2003 Joel de Guzman | ||
|  |     Copyright (c) 2002-2003 Martin Wille | ||
|  |     Copyright (c) 2003 Hartmut Kaiser | ||
|  |     http://spirit.sourceforge.net/ | ||
|  | 
 | ||
|  |     Use, modification and distribution is subject to the Boost Software | ||
|  |     License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | ||
|  |     http://www.boost.org/LICENSE_1_0.txt) | ||
|  | =============================================================================*/ | ||
|  | #if !defined BOOST_SPIRIT_GRAMMAR_IPP | ||
|  | #define BOOST_SPIRIT_GRAMMAR_IPP | ||
|  | 
 | ||
|  | #if !defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE) | ||
|  | #include <boost/spirit/home/classic/core/non_terminal/impl/object_with_id.ipp> | ||
|  | #include <algorithm> | ||
|  | #include <functional> | ||
|  | #include <memory> // for std::auto_ptr | ||
|  | #include <boost/weak_ptr.hpp> | ||
|  | #endif | ||
|  | 
 | ||
|  | #ifdef BOOST_SPIRIT_THREADSAFE | ||
|  | #include <boost/spirit/home/classic/core/non_terminal/impl/static.hpp> | ||
|  | #include <boost/thread/tss.hpp> | ||
|  | #include <boost/thread/mutex.hpp> | ||
|  | #include <boost/thread/lock_types.hpp> | ||
|  | #endif | ||
|  | 
 | ||
|  | /////////////////////////////////////////////////////////////////////////////// | ||
|  | namespace boost { namespace spirit { | ||
|  | 
 | ||
|  | BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN | ||
|  | 
 | ||
|  | template <typename DerivedT, typename ContextT> | ||
|  | struct grammar; | ||
|  | 
 | ||
|  | 
 | ||
|  | ////////////////////////////////// | ||
|  | template <typename GrammarT, typename ScannerT> | ||
|  | struct grammar_definition | ||
|  | { | ||
|  |     typedef typename GrammarT::template definition<ScannerT> type; | ||
|  | }; | ||
|  | 
 | ||
|  | 
 | ||
|  |     namespace impl | ||
|  |     { | ||
|  | 
 | ||
|  | #if !defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE) | ||
|  |     struct grammar_tag {}; | ||
|  | 
 | ||
|  |     ////////////////////////////////// | ||
|  |     template <typename GrammarT> | ||
|  |     struct grammar_helper_base | ||
|  |     { | ||
|  |         virtual int undefine(GrammarT *) = 0; | ||
|  |         virtual ~grammar_helper_base() {} | ||
|  |     }; | ||
|  | 
 | ||
|  |     ////////////////////////////////// | ||
|  |     template <typename GrammarT> | ||
|  |     struct grammar_helper_list | ||
|  |     { | ||
|  |         typedef GrammarT                      grammar_t; | ||
|  |         typedef grammar_helper_base<GrammarT> helper_t; | ||
|  |         typedef std::vector<helper_t*>        vector_t; | ||
|  | 
 | ||
|  |         grammar_helper_list() {} | ||
|  |         grammar_helper_list(grammar_helper_list const& /*x*/) | ||
|  |         {   // Does _not_ copy the helpers member ! | ||
|  |         } | ||
|  | 
 | ||
|  |         grammar_helper_list& operator=(grammar_helper_list const& x) | ||
|  |         {   // Does _not_ copy the helpers member ! | ||
|  |             return *this; | ||
|  |         } | ||
|  | 
 | ||
|  |         void push_back(helper_t *helper) | ||
|  |         { helpers.push_back(helper); } | ||
|  | 
 | ||
|  |         void pop_back() | ||
|  |         { helpers.pop_back(); } | ||
|  | 
 | ||
|  |         typename vector_t::size_type | ||
|  |         size() const | ||
|  |         { return helpers.size(); } | ||
|  | 
 | ||
|  |         typename vector_t::reverse_iterator | ||
|  |         rbegin() | ||
|  |         { return helpers.rbegin(); } | ||
|  | 
 | ||
|  |         typename vector_t::reverse_iterator | ||
|  |         rend() | ||
|  |         { return helpers.rend(); } | ||
|  | 
 | ||
|  | #ifdef BOOST_SPIRIT_THREADSAFE | ||
|  |         boost::mutex & mutex() | ||
|  |         { return m; } | ||
|  | #endif | ||
|  | 
 | ||
|  |     private: | ||
|  | 
 | ||
|  |         vector_t        helpers; | ||
|  | #ifdef BOOST_SPIRIT_THREADSAFE | ||
|  |         boost::mutex    m; | ||
|  | #endif | ||
|  |     }; | ||
|  | 
 | ||
|  |     ////////////////////////////////// | ||
|  |     struct grammartract_helper_list; | ||
|  | 
 | ||
|  | #if !defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE) | ||
|  | 
 | ||
|  |     struct grammartract_helper_list | ||
|  |     { | ||
|  |         template<typename GrammarT> | ||
|  |         static grammar_helper_list<GrammarT>& | ||
|  |         do_(GrammarT const* g) | ||
|  |         { | ||
|  |             return g->helpers; | ||
|  |         } | ||
|  |     }; | ||
|  | 
 | ||
|  | #endif | ||
|  | 
 | ||
|  |     ////////////////////////////////// | ||
|  |     template <typename GrammarT, typename DerivedT, typename ScannerT> | ||
|  |     struct grammar_helper : private grammar_helper_base<GrammarT> | ||
|  |     { | ||
|  |         typedef GrammarT grammar_t; | ||
|  |         typedef ScannerT scanner_t; | ||
|  |         typedef DerivedT derived_t; | ||
|  |         typedef typename grammar_definition<DerivedT, ScannerT>::type definition_t; | ||
|  | 
 | ||
|  |         typedef grammar_helper<grammar_t, derived_t, scanner_t> helper_t; | ||
|  |         typedef boost::shared_ptr<helper_t> helper_ptr_t; | ||
|  |         typedef boost::weak_ptr<helper_t>   helper_weak_ptr_t; | ||
|  | 
 | ||
|  |         grammar_helper* | ||
|  |         this_() { return this; } | ||
|  | 
 | ||
|  |         grammar_helper(helper_weak_ptr_t& p) | ||
|  |         : definitions_cnt(0) | ||
|  |         , self(this_()) | ||
|  |         { p = self; } | ||
|  | 
 | ||
|  |         definition_t& | ||
|  |         define(grammar_t const* target_grammar) | ||
|  |         { | ||
|  |             grammar_helper_list<GrammarT> &helpers = | ||
|  |             grammartract_helper_list::do_(target_grammar); | ||
|  |             typename grammar_t::object_id id = target_grammar->get_object_id(); | ||
|  | 
 | ||
|  |             if (definitions.size()<=id) | ||
|  |                 definitions.resize(id*3/2+1); | ||
|  |             if (definitions[id]!=0) | ||
|  |                 return *definitions[id]; | ||
|  | 
 | ||
|  |             std::auto_ptr<definition_t> | ||
|  |                 result(new definition_t(target_grammar->derived())); | ||
|  | 
 | ||
|  | #ifdef BOOST_SPIRIT_THREADSAFE | ||
|  |             boost::unique_lock<boost::mutex> lock(helpers.mutex()); | ||
|  | #endif | ||
|  |             helpers.push_back(this); | ||
|  | 
 | ||
|  |             ++definitions_cnt; | ||
|  |             definitions[id] = result.get(); | ||
|  |             return *(result.release()); | ||
|  |         } | ||
|  | 
 | ||
|  |         int | ||
|  |         undefine(grammar_t* target_grammar) | ||
|  |         { | ||
|  |             typename grammar_t::object_id id = target_grammar->get_object_id(); | ||
|  | 
 | ||
|  |             if (definitions.size()<=id) | ||
|  |                 return 0; | ||
|  |             delete definitions[id]; | ||
|  |             definitions[id] = 0; | ||
|  |             if (--definitions_cnt==0) | ||
|  |                 self.reset(); | ||
|  |             return 0; | ||
|  |         } | ||
|  | 
 | ||
|  |     private: | ||
|  | 
 | ||
|  |         std::vector<definition_t*>  definitions; | ||
|  |         unsigned long               definitions_cnt; | ||
|  |         helper_ptr_t                self; | ||
|  |     }; | ||
|  | 
 | ||
|  | #endif /* defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE) */ | ||
|  | 
 | ||
|  | #ifdef BOOST_SPIRIT_THREADSAFE | ||
|  |     class get_definition_static_data_tag | ||
|  |     { | ||
|  |         template<typename DerivedT, typename ContextT, typename ScannerT> | ||
|  |         friend typename DerivedT::template definition<ScannerT> & | ||
|  |             get_definition(grammar<DerivedT, ContextT> const*  self); | ||
|  | 
 | ||
|  |         get_definition_static_data_tag() {} | ||
|  |     }; | ||
|  | #endif | ||
|  | 
 | ||
|  |     template<typename DerivedT, typename ContextT, typename ScannerT> | ||
|  |     inline typename DerivedT::template definition<ScannerT> & | ||
|  |     get_definition(grammar<DerivedT, ContextT> const*  self) | ||
|  |     { | ||
|  | #if defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE) | ||
|  | 
 | ||
|  |         typedef typename DerivedT::template definition<ScannerT> definition_t; | ||
|  |         static definition_t def(self->derived()); | ||
|  |         return def; | ||
|  | #else | ||
|  |         typedef grammar<DerivedT, ContextT>                      self_t; | ||
|  |         typedef impl::grammar_helper<self_t, DerivedT, ScannerT> helper_t; | ||
|  |         typedef typename helper_t::helper_weak_ptr_t             ptr_t; | ||
|  | 
 | ||
|  | # ifdef BOOST_SPIRIT_THREADSAFE | ||
|  |         boost::thread_specific_ptr<ptr_t> & tld_helper | ||
|  |             = static_<boost::thread_specific_ptr<ptr_t>, | ||
|  |                 get_definition_static_data_tag>(get_definition_static_data_tag()); | ||
|  | 
 | ||
|  |         if (!tld_helper.get()) | ||
|  |             tld_helper.reset(new ptr_t); | ||
|  |         ptr_t &helper = *tld_helper; | ||
|  | # else | ||
|  |         static ptr_t helper; | ||
|  | # endif | ||
|  |         if (helper.expired()) | ||
|  |             new helper_t(helper); | ||
|  |         return helper.lock()->define(self); | ||
|  | #endif | ||
|  |     } | ||
|  | 
 | ||
|  |     template <int N> | ||
|  |     struct call_helper { | ||
|  | 
 | ||
|  |         template <typename RT, typename DefinitionT, typename ScannerT> | ||
|  |         static void | ||
|  |         do_ (RT &result, DefinitionT &def, ScannerT const &scan) | ||
|  |         { | ||
|  |             result = def.template get_start_parser<N>()->parse(scan); | ||
|  |         } | ||
|  |     }; | ||
|  | 
 | ||
|  |     template <> | ||
|  |     struct call_helper<0> { | ||
|  | 
 | ||
|  |         template <typename RT, typename DefinitionT, typename ScannerT> | ||
|  |         static void | ||
|  |         do_ (RT &result, DefinitionT &def, ScannerT const &scan) | ||
|  |         { | ||
|  |             result = def.start().parse(scan); | ||
|  |         } | ||
|  |     }; | ||
|  | 
 | ||
|  |     ////////////////////////////////// | ||
|  |     template<int N, typename DerivedT, typename ContextT, typename ScannerT> | ||
|  |     inline typename parser_result<grammar<DerivedT, ContextT>, ScannerT>::type | ||
|  |     grammar_parser_parse( | ||
|  |         grammar<DerivedT, ContextT> const*  self, | ||
|  |         ScannerT const &scan) | ||
|  |     { | ||
|  |         typedef | ||
|  |             typename parser_result<grammar<DerivedT, ContextT>, ScannerT>::type | ||
|  |             result_t; | ||
|  |         typedef typename DerivedT::template definition<ScannerT> definition_t; | ||
|  | 
 | ||
|  |         result_t result; | ||
|  |         definition_t &def = get_definition<DerivedT, ContextT, ScannerT>(self); | ||
|  | 
 | ||
|  |         call_helper<N>::do_(result, def, scan); | ||
|  |         return result; | ||
|  |     } | ||
|  | 
 | ||
|  |     ////////////////////////////////// | ||
|  |     template<typename GrammarT> | ||
|  |     inline void | ||
|  |     grammar_destruct(GrammarT* self) | ||
|  |     { | ||
|  | #if !defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE) | ||
|  |         typedef grammar_helper_list<GrammarT> helper_list_t; | ||
|  | 
 | ||
|  |         helper_list_t&  helpers = | ||
|  |         grammartract_helper_list::do_(self); | ||
|  | 
 | ||
|  | # if defined(BOOST_INTEL_CXX_VERSION) | ||
|  |         typedef typename helper_list_t::vector_t::reverse_iterator iterator_t; | ||
|  | 
 | ||
|  |         for (iterator_t i = helpers.rbegin(); i != helpers.rend(); ++i) | ||
|  |             (*i)->undefine(self); | ||
|  | # else | ||
|  |         typedef impl::grammar_helper_base<GrammarT> helper_base_t; | ||
|  | 
 | ||
|  |         std::for_each(helpers.rbegin(), helpers.rend(), | ||
|  |             std::bind2nd(std::mem_fun(&helper_base_t::undefine), self)); | ||
|  | # endif | ||
|  | 
 | ||
|  | #else | ||
|  |         (void)self; | ||
|  | #endif | ||
|  |     } | ||
|  | 
 | ||
|  |     /////////////////////////////////////////////////////////////////////////// | ||
|  |     // | ||
|  |     //  entry_grammar class | ||
|  |     // | ||
|  |     /////////////////////////////////////////////////////////////////////////// | ||
|  |     template <typename DerivedT, int N, typename ContextT> | ||
|  |     class entry_grammar | ||
|  |         : public parser<entry_grammar<DerivedT, N, ContextT> > | ||
|  |     { | ||
|  | 
 | ||
|  |     public: | ||
|  |         typedef entry_grammar<DerivedT, N, ContextT>    self_t; | ||
|  |         typedef self_t                                  embed_t; | ||
|  |         typedef typename ContextT::context_linker_t     context_t; | ||
|  |         typedef typename context_t::attr_t              attr_t; | ||
|  | 
 | ||
|  |         template <typename ScannerT> | ||
|  |         struct result | ||
|  |         { | ||
|  |             typedef typename match_result<ScannerT, attr_t>::type type; | ||
|  |         }; | ||
|  | 
 | ||
|  |         entry_grammar(DerivedT const &p) : target_grammar(p) {} | ||
|  | 
 | ||
|  |         template <typename ScannerT> | ||
|  |         typename parser_result<self_t, ScannerT>::type | ||
|  |         parse_main(ScannerT const& scan) const | ||
|  |         { return impl::grammar_parser_parse<N>(&target_grammar, scan); } | ||
|  | 
 | ||
|  |         template <typename ScannerT> | ||
|  |         typename parser_result<self_t, ScannerT>::type | ||
|  |         parse(ScannerT const& scan) const | ||
|  |         { | ||
|  |             typedef typename parser_result<self_t, ScannerT>::type result_t; | ||
|  |             typedef parser_scanner_linker<ScannerT> scanner_t; | ||
|  |             BOOST_SPIRIT_CONTEXT_PARSE(scan, target_grammar, scanner_t, | ||
|  |                 context_t, result_t) | ||
|  |         } | ||
|  | 
 | ||
|  |     private: | ||
|  |         DerivedT const &target_grammar; | ||
|  |     }; | ||
|  | 
 | ||
|  |     } // namespace impl | ||
|  | 
 | ||
|  | /////////////////////////////////////// | ||
|  | #if !defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE) | ||
|  | #define BOOST_SPIRIT_GRAMMAR_ID , public impl::object_with_id<impl::grammar_tag> | ||
|  | #else | ||
|  | #define BOOST_SPIRIT_GRAMMAR_ID | ||
|  | #endif | ||
|  | 
 | ||
|  | /////////////////////////////////////// | ||
|  | #if !defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE) | ||
|  | #define BOOST_SPIRIT_GRAMMAR_STATE                            \ | ||
|  |     private:                                                  \ | ||
|  |     friend struct impl::grammartract_helper_list;    \ | ||
|  |     mutable impl::grammar_helper_list<self_t> helpers; | ||
|  | #else | ||
|  | #define BOOST_SPIRIT_GRAMMAR_STATE | ||
|  | #endif | ||
|  | 
 | ||
|  | /////////////////////////////////////////////////////////////////////////////// | ||
|  | BOOST_SPIRIT_CLASSIC_NAMESPACE_END | ||
|  | 
 | ||
|  | }} // namespace boost::spirit | ||
|  | 
 | ||
|  | #endif |