/*============================================================================= | |
Copyright (c) 2002-2003 Joel de Guzman | |
Copyright (c) 2002-2003 Hartmut Kaiser | |
http://spirit.sourceforge.net/ | |
Distributed under 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_PARSER_CONTEXT_HPP) | |
#define BOOST_SPIRIT_PARSER_CONTEXT_HPP | |
/////////////////////////////////////////////////////////////////////////////// | |
namespace boost | |
{ | |
namespace spirit | |
{ | |
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN | |
/////////////////////////////////////////////////////////////////////////// | |
// | |
// default_parser_context_base class { default context base } | |
// | |
/////////////////////////////////////////////////////////////////////////// | |
struct default_parser_context_base | |
{ | |
template <typename DerivedT> | |
struct aux {}; | |
}; | |
/////////////////////////////////////////////////////////////////////////// | |
// | |
// parser_context_base class { base class of all context classes } | |
// | |
/////////////////////////////////////////////////////////////////////////// | |
struct parser_context_base {}; | |
/////////////////////////////////////////////////////////////////////////// | |
// | |
// parser_context class { default context } | |
// | |
/////////////////////////////////////////////////////////////////////////// | |
struct nil_t; | |
template<typename ContextT> struct parser_context_linker; | |
template<typename AttrT = nil_t> | |
struct parser_context : parser_context_base | |
{ | |
typedef AttrT attr_t; | |
typedef default_parser_context_base base_t; | |
typedef parser_context_linker<parser_context<AttrT> > context_linker_t; | |
template <typename ParserT> | |
parser_context(ParserT const&) {} | |
template <typename ParserT, typename ScannerT> | |
void | |
pre_parse(ParserT const&, ScannerT const&) {} | |
template <typename ResultT, typename ParserT, typename ScannerT> | |
ResultT& | |
post_parse(ResultT& hit, ParserT const&, ScannerT const&) | |
{ return hit; } | |
}; | |
/////////////////////////////////////////////////////////////////////////// | |
// | |
// context_aux class | |
// | |
// context_aux<ContextT, DerivedT> is a class derived from the | |
// ContextT's nested base_t::base<DerivedT> template class. (see | |
// default_parser_context_base::aux for an example). | |
// | |
// Basically, this class provides ContextT dependent optional | |
// functionality to the derived class DerivedT through the CRTP | |
// idiom (Curiously recurring template pattern). | |
// | |
/////////////////////////////////////////////////////////////////////////// | |
template <typename ContextT, typename DerivedT> | |
struct context_aux : public ContextT::base_t::template aux<DerivedT> {}; | |
/////////////////////////////////////////////////////////////////////////// | |
// | |
// parser_scanner_linker and parser_scanner_linker classes | |
// { helper templates for the rule extensibility } | |
// | |
// This classes can be 'overloaded' (defined elsewhere), to plug | |
// in additional functionality into the non-terminal parsing process. | |
// | |
/////////////////////////////////////////////////////////////////////////// | |
#if !defined(BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED) | |
#define BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED | |
template<typename ScannerT> | |
struct parser_scanner_linker : public ScannerT | |
{ | |
parser_scanner_linker(ScannerT const scan_) : ScannerT(scan_) {} | |
}; | |
#endif // !defined(BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED) | |
////////////////////////////////// | |
#if !defined(BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED) | |
#define BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED | |
template<typename ContextT> | |
struct parser_context_linker : public ContextT | |
{ | |
template <typename ParserT> | |
parser_context_linker(ParserT const& p) | |
: ContextT(p) {} | |
template <typename ParserT, typename ScannerT> | |
void pre_parse(ParserT const& p, ScannerT const& scan) | |
{ ContextT::pre_parse(p, scan); } | |
template <typename ResultT, typename ParserT, typename ScannerT> | |
ResultT& | |
post_parse(ResultT& hit, ParserT const& p, ScannerT const& scan) | |
{ return ContextT::post_parse(hit, p, scan); } | |
}; | |
#endif // !defined(BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED) | |
/////////////////////////////////////////////////////////////////////////// | |
// | |
// BOOST_SPIRIT_CONTEXT_PARSE helper macro | |
// | |
// The original implementation uses a template class. However, we | |
// need to lessen the template instantiation depth to help inferior | |
// compilers that sometimes choke on deep template instantiations. | |
// The objective is to avoid code redundancy. A macro, in this case | |
// is an obvious solution. Sigh! | |
// | |
// WARNING: INTERNAL USE ONLY. NOT FOR PUBLIC CONSUMPTION. | |
// | |
/////////////////////////////////////////////////////////////////////////// | |
#define BOOST_SPIRIT_CONTEXT_PARSE(scan, this_, scanner_t, context_t, result_t) \ | |
scanner_t scan_wrap(scan); \ | |
context_t context_wrap(this_); \ | |
context_wrap.pre_parse(this_, scan_wrap); \ | |
result_t hit = parse_main(scan); \ | |
return context_wrap.post_parse(hit, this_, scan_wrap); | |
BOOST_SPIRIT_CLASSIC_NAMESPACE_END | |
} // namespace spirit | |
} // namespace boost | |
#endif |