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