1/*============================================================================= 2 Copyright (c) 2002-2003 Hartmut Kaiser 3 http://spirit.sourceforge.net/ 4 5 Use, modification and distribution is subject to the Boost Software 6 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 7 http://www.boost.org/LICENSE_1_0.txt) 8=============================================================================*/ 9#ifndef BOOST_SPIRIT_CONFIX_IPP 10#define BOOST_SPIRIT_CONFIX_IPP 11 12/////////////////////////////////////////////////////////////////////////////// 13#include <boost/spirit/home/classic/meta/refactoring.hpp> 14#include <boost/spirit/home/classic/core/composite/impl/directives.ipp> 15 16/////////////////////////////////////////////////////////////////////////////// 17namespace boost { namespace spirit { 18 19BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN 20 21/////////////////////////////////////////////////////////////////////////////// 22// 23// Types to distinguish nested and non-nested confix parsers 24// 25/////////////////////////////////////////////////////////////////////////////// 26struct is_nested {}; 27struct non_nested {}; 28 29/////////////////////////////////////////////////////////////////////////////// 30// 31// Types to distinguish between confix parsers, which are implicitly lexems 32// and without this behaviour 33// 34/////////////////////////////////////////////////////////////////////////////// 35struct is_lexeme {}; 36struct non_lexeme {}; 37 38/////////////////////////////////////////////////////////////////////////////// 39// 40// confix_parser_type class implementation 41// 42/////////////////////////////////////////////////////////////////////////////// 43namespace impl { 44 45 /////////////////////////////////////////////////////////////////////////// 46 // implicitly insert a lexeme_d into the parsing process 47 48 template <typename LexemeT> 49 struct select_confix_parse_lexeme; 50 51 template <> 52 struct select_confix_parse_lexeme<is_lexeme> { 53 54 template <typename ParserT, typename ScannerT> 55 static typename parser_result<ParserT, ScannerT>::type 56 parse(ParserT const& p, ScannerT const& scan) 57 { 58 typedef typename parser_result<ParserT, ScannerT>::type result_t; 59 return contiguous_parser_parse<result_t>(p, scan, scan); 60 } 61 }; 62 63 template <> 64 struct select_confix_parse_lexeme<non_lexeme> { 65 66 template <typename ParserT, typename ScannerT> 67 static typename parser_result<ParserT, ScannerT>::type 68 parse(ParserT const& p, ScannerT const& scan) 69 { 70 return p.parse(scan); 71 } 72 }; 73 74 /////////////////////////////////////////////////////////////////////////// 75 // parse confix sequences with refactoring 76 77 template <typename NestedT> 78 struct select_confix_parse_refactor; 79 80 template <> 81 struct select_confix_parse_refactor<is_nested> { 82 83 template < 84 typename LexemeT, typename ParserT, typename ScannerT, 85 typename OpenT, typename ExprT, typename CloseT 86 > 87 static typename parser_result<ParserT, ScannerT>::type 88 parse( 89 LexemeT const &, ParserT const& this_, ScannerT const& scan, 90 OpenT const& open, ExprT const& expr, CloseT const& close) 91 { 92 typedef refactor_action_gen<refactor_unary_gen<> > refactor_t; 93 const refactor_t refactor_body_d = refactor_t(refactor_unary_d); 94 95 return select_confix_parse_lexeme<LexemeT>::parse(( 96 open 97 >> (this_ | refactor_body_d[expr - close]) 98 >> close 99 ), scan); 100 } 101 }; 102 103 template <> 104 struct select_confix_parse_refactor<non_nested> { 105 106 template < 107 typename LexemeT, typename ParserT, typename ScannerT, 108 typename OpenT, typename ExprT, typename CloseT 109 > 110 static typename parser_result<ParserT, ScannerT>::type 111 parse( 112 LexemeT const &, ParserT const& /*this_*/, ScannerT const& scan, 113 OpenT const& open, ExprT const& expr, CloseT const& close) 114 { 115 typedef refactor_action_gen<refactor_unary_gen<> > refactor_t; 116 const refactor_t refactor_body_d = refactor_t(refactor_unary_d); 117 118 return select_confix_parse_lexeme<LexemeT>::parse(( 119 open 120 >> refactor_body_d[expr - close] 121 >> close 122 ), scan); 123 } 124 }; 125 126 /////////////////////////////////////////////////////////////////////////// 127 // parse confix sequences without refactoring 128 129 template <typename NestedT> 130 struct select_confix_parse_no_refactor; 131 132 template <> 133 struct select_confix_parse_no_refactor<is_nested> { 134 135 template < 136 typename LexemeT, typename ParserT, typename ScannerT, 137 typename OpenT, typename ExprT, typename CloseT 138 > 139 static typename parser_result<ParserT, ScannerT>::type 140 parse( 141 LexemeT const &, ParserT const& this_, ScannerT const& scan, 142 OpenT const& open, ExprT const& expr, CloseT const& close) 143 { 144 return select_confix_parse_lexeme<LexemeT>::parse(( 145 open 146 >> (this_ | (expr - close)) 147 >> close 148 ), scan); 149 } 150 }; 151 152 template <> 153 struct select_confix_parse_no_refactor<non_nested> { 154 155 template < 156 typename LexemeT, typename ParserT, typename ScannerT, 157 typename OpenT, typename ExprT, typename CloseT 158 > 159 static typename parser_result<ParserT, ScannerT>::type 160 parse( 161 LexemeT const &, ParserT const & /*this_*/, ScannerT const& scan, 162 OpenT const& open, ExprT const& expr, CloseT const& close) 163 { 164 return select_confix_parse_lexeme<LexemeT>::parse(( 165 open 166 >> (expr - close) 167 >> close 168 ), scan); 169 } 170 }; 171 172 // the refactoring is handled by the refactoring parsers, so here there 173 // is no need to pay attention to these issues. 174 175 template <typename CategoryT> 176 struct confix_parser_type { 177 178 template < 179 typename NestedT, typename LexemeT, 180 typename ParserT, typename ScannerT, 181 typename OpenT, typename ExprT, typename CloseT 182 > 183 static typename parser_result<ParserT, ScannerT>::type 184 parse( 185 NestedT const &, LexemeT const &lexeme, 186 ParserT const& this_, ScannerT const& scan, 187 OpenT const& open, ExprT const& expr, CloseT const& close) 188 { 189 return select_confix_parse_refactor<NestedT>:: 190 parse(lexeme, this_, scan, open, expr, close); 191 } 192 }; 193 194 template <> 195 struct confix_parser_type<plain_parser_category> { 196 197 template < 198 typename NestedT, typename LexemeT, 199 typename ParserT, typename ScannerT, 200 typename OpenT, typename ExprT, typename CloseT 201 > 202 static typename parser_result<ParserT, ScannerT>::type 203 parse( 204 NestedT const &, LexemeT const &lexeme, 205 ParserT const& this_, ScannerT const& scan, 206 OpenT const& open, ExprT const& expr, CloseT const& close) 207 { 208 return select_confix_parse_no_refactor<NestedT>:: 209 parse(lexeme, this_, scan, open, expr, close); 210 } 211 }; 212 213} // namespace impl 214 215/////////////////////////////////////////////////////////////////////////////// 216BOOST_SPIRIT_CLASSIC_NAMESPACE_END 217 218}} // namespace boost::spirit 219 220#endif 221 222