151 lines
5.9 KiB
Plaintext
151 lines
5.9 KiB
Plaintext
/*=============================================================================
|
|
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
|