Chris@16: /*============================================================================= Chris@16: Copyright (c) 2002-2003 Hartmut Kaiser Chris@16: http://spirit.sourceforge.net/ Chris@16: Chris@16: Use, modification and distribution is subject to the Boost Software Chris@16: License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@16: http://www.boost.org/LICENSE_1_0.txt) Chris@16: =============================================================================*/ Chris@16: #ifndef BOOST_SPIRIT_CONFIX_IPP Chris@16: #define BOOST_SPIRIT_CONFIX_IPP Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: #include Chris@16: #include Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: namespace boost { namespace spirit { Chris@16: Chris@16: BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // Types to distinguish nested and non-nested confix parsers Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct is_nested {}; Chris@16: struct non_nested {}; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // Types to distinguish between confix parsers, which are implicitly lexems Chris@16: // and without this behaviour Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct is_lexeme {}; Chris@16: struct non_lexeme {}; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // confix_parser_type class implementation Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: namespace impl { Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // implicitly insert a lexeme_d into the parsing process Chris@16: Chris@16: template Chris@16: struct select_confix_parse_lexeme; Chris@16: Chris@16: template <> Chris@16: struct select_confix_parse_lexeme { Chris@16: Chris@16: template Chris@16: static typename parser_result::type Chris@16: parse(ParserT const& p, ScannerT const& scan) Chris@16: { Chris@16: typedef typename parser_result::type result_t; Chris@16: return contiguous_parser_parse(p, scan, scan); Chris@16: } Chris@16: }; Chris@16: Chris@16: template <> Chris@16: struct select_confix_parse_lexeme { Chris@16: Chris@16: template Chris@16: static typename parser_result::type Chris@16: parse(ParserT const& p, ScannerT const& scan) Chris@16: { Chris@16: return p.parse(scan); Chris@16: } Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // parse confix sequences with refactoring Chris@16: Chris@16: template Chris@16: struct select_confix_parse_refactor; Chris@16: Chris@16: template <> Chris@16: struct select_confix_parse_refactor { Chris@16: Chris@16: template < Chris@16: typename LexemeT, typename ParserT, typename ScannerT, Chris@16: typename OpenT, typename ExprT, typename CloseT Chris@16: > Chris@16: static typename parser_result::type Chris@16: parse( Chris@16: LexemeT const &, ParserT const& this_, ScannerT const& scan, Chris@16: OpenT const& open, ExprT const& expr, CloseT const& close) Chris@16: { Chris@16: typedef refactor_action_gen > refactor_t; Chris@16: const refactor_t refactor_body_d = refactor_t(refactor_unary_d); Chris@16: Chris@16: return select_confix_parse_lexeme::parse(( Chris@16: open Chris@16: >> (this_ | refactor_body_d[expr - close]) Chris@16: >> close Chris@16: ), scan); Chris@16: } Chris@16: }; Chris@16: Chris@16: template <> Chris@16: struct select_confix_parse_refactor { Chris@16: Chris@16: template < Chris@16: typename LexemeT, typename ParserT, typename ScannerT, Chris@16: typename OpenT, typename ExprT, typename CloseT Chris@16: > Chris@16: static typename parser_result::type Chris@16: parse( Chris@16: LexemeT const &, ParserT const& /*this_*/, ScannerT const& scan, Chris@16: OpenT const& open, ExprT const& expr, CloseT const& close) Chris@16: { Chris@16: typedef refactor_action_gen > refactor_t; Chris@16: const refactor_t refactor_body_d = refactor_t(refactor_unary_d); Chris@16: Chris@16: return select_confix_parse_lexeme::parse(( Chris@16: open Chris@16: >> refactor_body_d[expr - close] Chris@16: >> close Chris@16: ), scan); Chris@16: } Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // parse confix sequences without refactoring Chris@16: Chris@16: template Chris@16: struct select_confix_parse_no_refactor; Chris@16: Chris@16: template <> Chris@16: struct select_confix_parse_no_refactor { Chris@16: Chris@16: template < Chris@16: typename LexemeT, typename ParserT, typename ScannerT, Chris@16: typename OpenT, typename ExprT, typename CloseT Chris@16: > Chris@16: static typename parser_result::type Chris@16: parse( Chris@16: LexemeT const &, ParserT const& this_, ScannerT const& scan, Chris@16: OpenT const& open, ExprT const& expr, CloseT const& close) Chris@16: { Chris@16: return select_confix_parse_lexeme::parse(( Chris@16: open Chris@16: >> (this_ | (expr - close)) Chris@16: >> close Chris@16: ), scan); Chris@16: } Chris@16: }; Chris@16: Chris@16: template <> Chris@16: struct select_confix_parse_no_refactor { Chris@16: Chris@16: template < Chris@16: typename LexemeT, typename ParserT, typename ScannerT, Chris@16: typename OpenT, typename ExprT, typename CloseT Chris@16: > Chris@16: static typename parser_result::type Chris@16: parse( Chris@16: LexemeT const &, ParserT const & /*this_*/, ScannerT const& scan, Chris@16: OpenT const& open, ExprT const& expr, CloseT const& close) Chris@16: { Chris@16: return select_confix_parse_lexeme::parse(( Chris@16: open Chris@16: >> (expr - close) Chris@16: >> close Chris@16: ), scan); Chris@16: } Chris@16: }; Chris@16: Chris@16: // the refactoring is handled by the refactoring parsers, so here there Chris@16: // is no need to pay attention to these issues. Chris@16: Chris@16: template Chris@16: struct confix_parser_type { Chris@16: Chris@16: template < Chris@16: typename NestedT, typename LexemeT, Chris@16: typename ParserT, typename ScannerT, Chris@16: typename OpenT, typename ExprT, typename CloseT Chris@16: > Chris@16: static typename parser_result::type Chris@16: parse( Chris@16: NestedT const &, LexemeT const &lexeme, Chris@16: ParserT const& this_, ScannerT const& scan, Chris@16: OpenT const& open, ExprT const& expr, CloseT const& close) Chris@16: { Chris@16: return select_confix_parse_refactor:: Chris@16: parse(lexeme, this_, scan, open, expr, close); Chris@16: } Chris@16: }; Chris@16: Chris@16: template <> Chris@16: struct confix_parser_type { Chris@16: Chris@16: template < Chris@16: typename NestedT, typename LexemeT, Chris@16: typename ParserT, typename ScannerT, Chris@16: typename OpenT, typename ExprT, typename CloseT Chris@16: > Chris@16: static typename parser_result::type Chris@16: parse( Chris@16: NestedT const &, LexemeT const &lexeme, Chris@16: ParserT const& this_, ScannerT const& scan, Chris@16: OpenT const& open, ExprT const& expr, CloseT const& close) Chris@16: { Chris@16: return select_confix_parse_no_refactor:: Chris@16: parse(lexeme, this_, scan, open, expr, close); Chris@16: } Chris@16: }; Chris@16: Chris@16: } // namespace impl Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: BOOST_SPIRIT_CLASSIC_NAMESPACE_END Chris@16: Chris@16: }} // namespace boost::spirit Chris@16: Chris@16: #endif Chris@16: