You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
221 lines
7.6 KiB
221 lines
7.6 KiB
/*============================================================================= |
|
Copyright (c) 2002-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) |
|
=============================================================================*/ |
|
#ifndef BOOST_SPIRIT_CONFIX_IPP |
|
#define BOOST_SPIRIT_CONFIX_IPP |
|
|
|
/////////////////////////////////////////////////////////////////////////////// |
|
#include <boost/spirit/home/classic/meta/refactoring.hpp> |
|
#include <boost/spirit/home/classic/core/composite/impl/directives.ipp> |
|
|
|
/////////////////////////////////////////////////////////////////////////////// |
|
namespace boost { namespace spirit { |
|
|
|
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN |
|
|
|
/////////////////////////////////////////////////////////////////////////////// |
|
// |
|
// Types to distinguish nested and non-nested confix parsers |
|
// |
|
/////////////////////////////////////////////////////////////////////////////// |
|
struct is_nested {}; |
|
struct non_nested {}; |
|
|
|
/////////////////////////////////////////////////////////////////////////////// |
|
// |
|
// Types to distinguish between confix parsers, which are implicitly lexems |
|
// and without this behaviour |
|
// |
|
/////////////////////////////////////////////////////////////////////////////// |
|
struct is_lexeme {}; |
|
struct non_lexeme {}; |
|
|
|
/////////////////////////////////////////////////////////////////////////////// |
|
// |
|
// confix_parser_type class implementation |
|
// |
|
/////////////////////////////////////////////////////////////////////////////// |
|
namespace impl { |
|
|
|
/////////////////////////////////////////////////////////////////////////// |
|
// implicitly insert a lexeme_d into the parsing process |
|
|
|
template <typename LexemeT> |
|
struct select_confix_parse_lexeme; |
|
|
|
template <> |
|
struct select_confix_parse_lexeme<is_lexeme> { |
|
|
|
template <typename ParserT, typename ScannerT> |
|
static typename parser_result<ParserT, ScannerT>::type |
|
parse(ParserT const& p, ScannerT const& scan) |
|
{ |
|
typedef typename parser_result<ParserT, ScannerT>::type result_t; |
|
return contiguous_parser_parse<result_t>(p, scan, scan); |
|
} |
|
}; |
|
|
|
template <> |
|
struct select_confix_parse_lexeme<non_lexeme> { |
|
|
|
template <typename ParserT, typename ScannerT> |
|
static typename parser_result<ParserT, ScannerT>::type |
|
parse(ParserT const& p, ScannerT const& scan) |
|
{ |
|
return p.parse(scan); |
|
} |
|
}; |
|
|
|
/////////////////////////////////////////////////////////////////////////// |
|
// parse confix sequences with refactoring |
|
|
|
template <typename NestedT> |
|
struct select_confix_parse_refactor; |
|
|
|
template <> |
|
struct select_confix_parse_refactor<is_nested> { |
|
|
|
template < |
|
typename LexemeT, typename ParserT, typename ScannerT, |
|
typename OpenT, typename ExprT, typename CloseT |
|
> |
|
static typename parser_result<ParserT, ScannerT>::type |
|
parse( |
|
LexemeT const &, ParserT const& this_, ScannerT const& scan, |
|
OpenT const& open, ExprT const& expr, CloseT const& close) |
|
{ |
|
typedef refactor_action_gen<refactor_unary_gen<> > refactor_t; |
|
const refactor_t refactor_body_d = refactor_t(refactor_unary_d); |
|
|
|
return select_confix_parse_lexeme<LexemeT>::parse(( |
|
open |
|
>> (this_ | refactor_body_d[expr - close]) |
|
>> close |
|
), scan); |
|
} |
|
}; |
|
|
|
template <> |
|
struct select_confix_parse_refactor<non_nested> { |
|
|
|
template < |
|
typename LexemeT, typename ParserT, typename ScannerT, |
|
typename OpenT, typename ExprT, typename CloseT |
|
> |
|
static typename parser_result<ParserT, ScannerT>::type |
|
parse( |
|
LexemeT const &, ParserT const& /*this_*/, ScannerT const& scan, |
|
OpenT const& open, ExprT const& expr, CloseT const& close) |
|
{ |
|
typedef refactor_action_gen<refactor_unary_gen<> > refactor_t; |
|
const refactor_t refactor_body_d = refactor_t(refactor_unary_d); |
|
|
|
return select_confix_parse_lexeme<LexemeT>::parse(( |
|
open |
|
>> refactor_body_d[expr - close] |
|
>> close |
|
), scan); |
|
} |
|
}; |
|
|
|
/////////////////////////////////////////////////////////////////////////// |
|
// parse confix sequences without refactoring |
|
|
|
template <typename NestedT> |
|
struct select_confix_parse_no_refactor; |
|
|
|
template <> |
|
struct select_confix_parse_no_refactor<is_nested> { |
|
|
|
template < |
|
typename LexemeT, typename ParserT, typename ScannerT, |
|
typename OpenT, typename ExprT, typename CloseT |
|
> |
|
static typename parser_result<ParserT, ScannerT>::type |
|
parse( |
|
LexemeT const &, ParserT const& this_, ScannerT const& scan, |
|
OpenT const& open, ExprT const& expr, CloseT const& close) |
|
{ |
|
return select_confix_parse_lexeme<LexemeT>::parse(( |
|
open |
|
>> (this_ | (expr - close)) |
|
>> close |
|
), scan); |
|
} |
|
}; |
|
|
|
template <> |
|
struct select_confix_parse_no_refactor<non_nested> { |
|
|
|
template < |
|
typename LexemeT, typename ParserT, typename ScannerT, |
|
typename OpenT, typename ExprT, typename CloseT |
|
> |
|
static typename parser_result<ParserT, ScannerT>::type |
|
parse( |
|
LexemeT const &, ParserT const & /*this_*/, ScannerT const& scan, |
|
OpenT const& open, ExprT const& expr, CloseT const& close) |
|
{ |
|
return select_confix_parse_lexeme<LexemeT>::parse(( |
|
open |
|
>> (expr - close) |
|
>> close |
|
), scan); |
|
} |
|
}; |
|
|
|
// the refactoring is handled by the refactoring parsers, so here there |
|
// is no need to pay attention to these issues. |
|
|
|
template <typename CategoryT> |
|
struct confix_parser_type { |
|
|
|
template < |
|
typename NestedT, typename LexemeT, |
|
typename ParserT, typename ScannerT, |
|
typename OpenT, typename ExprT, typename CloseT |
|
> |
|
static typename parser_result<ParserT, ScannerT>::type |
|
parse( |
|
NestedT const &, LexemeT const &lexeme, |
|
ParserT const& this_, ScannerT const& scan, |
|
OpenT const& open, ExprT const& expr, CloseT const& close) |
|
{ |
|
return select_confix_parse_refactor<NestedT>:: |
|
parse(lexeme, this_, scan, open, expr, close); |
|
} |
|
}; |
|
|
|
template <> |
|
struct confix_parser_type<plain_parser_category> { |
|
|
|
template < |
|
typename NestedT, typename LexemeT, |
|
typename ParserT, typename ScannerT, |
|
typename OpenT, typename ExprT, typename CloseT |
|
> |
|
static typename parser_result<ParserT, ScannerT>::type |
|
parse( |
|
NestedT const &, LexemeT const &lexeme, |
|
ParserT const& this_, ScannerT const& scan, |
|
OpenT const& open, ExprT const& expr, CloseT const& close) |
|
{ |
|
return select_confix_parse_no_refactor<NestedT>:: |
|
parse(lexeme, this_, scan, open, expr, close); |
|
} |
|
}; |
|
|
|
} // namespace impl |
|
|
|
/////////////////////////////////////////////////////////////////////////////// |
|
BOOST_SPIRIT_CLASSIC_NAMESPACE_END |
|
|
|
}} // namespace boost::spirit |
|
|
|
#endif |
|
|
|
|