[857] | 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 | ///////////////////////////////////////////////////////////////////////////////
|
---|
| 28 | namespace boost { namespace spirit {
|
---|
| 29 |
|
---|
| 30 | template <typename DerivedT, typename ContextT>
|
---|
| 31 | struct grammar;
|
---|
| 32 |
|
---|
| 33 | #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1200)
|
---|
| 34 |
|
---|
| 35 | BOOST_SPIRIT_DEPENDENT_TEMPLATE_WRAPPER(grammar_definition_wrapper, definition);
|
---|
| 36 |
|
---|
| 37 | //////////////////////////////////
|
---|
| 38 | template <typename GrammarT, typename ScannerT>
|
---|
| 39 | struct grammar_definition
|
---|
| 40 | {
|
---|
| 41 | typedef typename impl::grammar_definition_wrapper<GrammarT>
|
---|
| 42 | ::template result_<ScannerT>::param_t type;
|
---|
| 43 | };
|
---|
| 44 |
|
---|
| 45 | #else
|
---|
| 46 |
|
---|
| 47 | //////////////////////////////////
|
---|
| 48 | template <typename GrammarT, typename ScannerT>
|
---|
| 49 | struct 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
|
---|