1 /*=============================================================================
2 Copyright (c) 2002-2003 Hartmut Kaiser
3 http://spirit.sourceforge.net/
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
12 ///////////////////////////////////////////////////////////////////////////////
13 #include <boost/spirit/home/classic/meta/refactoring.hpp>
14 #include <boost/spirit/home/classic/core/composite/impl/directives.ipp>
16 ///////////////////////////////////////////////////////////////////////////////
17 namespace boost { namespace spirit {
19 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
21 ///////////////////////////////////////////////////////////////////////////////
23 // Types to distinguish nested and non-nested confix parsers
25 ///////////////////////////////////////////////////////////////////////////////
29 ///////////////////////////////////////////////////////////////////////////////
31 // Types to distinguish between confix parsers, which are implicitly lexems
32 // and without this behaviour
34 ///////////////////////////////////////////////////////////////////////////////
38 ///////////////////////////////////////////////////////////////////////////////
40 // confix_parser_type class implementation
42 ///////////////////////////////////////////////////////////////////////////////
45 ///////////////////////////////////////////////////////////////////////////
46 // implicitly insert a lexeme_d into the parsing process
48 template <typename LexemeT>
49 struct select_confix_parse_lexeme;
52 struct select_confix_parse_lexeme<is_lexeme> {
54 template <typename ParserT, typename ScannerT>
55 static typename parser_result<ParserT, ScannerT>::type
56 parse(ParserT const& p, ScannerT const& scan)
58 typedef typename parser_result<ParserT, ScannerT>::type result_t;
59 return contiguous_parser_parse<result_t>(p, scan, scan);
64 struct select_confix_parse_lexeme<non_lexeme> {
66 template <typename ParserT, typename ScannerT>
67 static typename parser_result<ParserT, ScannerT>::type
68 parse(ParserT const& p, ScannerT const& scan)
74 ///////////////////////////////////////////////////////////////////////////
75 // parse confix sequences with refactoring
77 template <typename NestedT>
78 struct select_confix_parse_refactor;
81 struct select_confix_parse_refactor<is_nested> {
84 typename LexemeT, typename ParserT, typename ScannerT,
85 typename OpenT, typename ExprT, typename CloseT
87 static typename parser_result<ParserT, ScannerT>::type
89 LexemeT const &, ParserT const& this_, ScannerT const& scan,
90 OpenT const& open, ExprT const& expr, CloseT const& close)
92 typedef refactor_action_gen<refactor_unary_gen<> > refactor_t;
93 const refactor_t refactor_body_d = refactor_t(refactor_unary_d);
95 return select_confix_parse_lexeme<LexemeT>::parse((
97 >> (this_ | refactor_body_d[expr - close])
104 struct select_confix_parse_refactor<non_nested> {
107 typename LexemeT, typename ParserT, typename ScannerT,
108 typename OpenT, typename ExprT, typename CloseT
110 static typename parser_result<ParserT, ScannerT>::type
112 LexemeT const &, ParserT const& /*this_*/, ScannerT const& scan,
113 OpenT const& open, ExprT const& expr, CloseT const& close)
115 typedef refactor_action_gen<refactor_unary_gen<> > refactor_t;
116 const refactor_t refactor_body_d = refactor_t(refactor_unary_d);
118 return select_confix_parse_lexeme<LexemeT>::parse((
120 >> refactor_body_d[expr - close]
126 ///////////////////////////////////////////////////////////////////////////
127 // parse confix sequences without refactoring
129 template <typename NestedT>
130 struct select_confix_parse_no_refactor;
133 struct select_confix_parse_no_refactor<is_nested> {
136 typename LexemeT, typename ParserT, typename ScannerT,
137 typename OpenT, typename ExprT, typename CloseT
139 static typename parser_result<ParserT, ScannerT>::type
141 LexemeT const &, ParserT const& this_, ScannerT const& scan,
142 OpenT const& open, ExprT const& expr, CloseT const& close)
144 return select_confix_parse_lexeme<LexemeT>::parse((
146 >> (this_ | (expr - close))
153 struct select_confix_parse_no_refactor<non_nested> {
156 typename LexemeT, typename ParserT, typename ScannerT,
157 typename OpenT, typename ExprT, typename CloseT
159 static typename parser_result<ParserT, ScannerT>::type
161 LexemeT const &, ParserT const & /*this_*/, ScannerT const& scan,
162 OpenT const& open, ExprT const& expr, CloseT const& close)
164 return select_confix_parse_lexeme<LexemeT>::parse((
172 // the refactoring is handled by the refactoring parsers, so here there
173 // is no need to pay attention to these issues.
175 template <typename CategoryT>
176 struct confix_parser_type {
179 typename NestedT, typename LexemeT,
180 typename ParserT, typename ScannerT,
181 typename OpenT, typename ExprT, typename CloseT
183 static typename parser_result<ParserT, ScannerT>::type
185 NestedT const &, LexemeT const &lexeme,
186 ParserT const& this_, ScannerT const& scan,
187 OpenT const& open, ExprT const& expr, CloseT const& close)
189 return select_confix_parse_refactor<NestedT>::
190 parse(lexeme, this_, scan, open, expr, close);
195 struct confix_parser_type<plain_parser_category> {
198 typename NestedT, typename LexemeT,
199 typename ParserT, typename ScannerT,
200 typename OpenT, typename ExprT, typename CloseT
202 static typename parser_result<ParserT, ScannerT>::type
204 NestedT const &, LexemeT const &lexeme,
205 ParserT const& this_, ScannerT const& scan,
206 OpenT const& open, ExprT const& expr, CloseT const& close)
208 return select_confix_parse_no_refactor<NestedT>::
209 parse(lexeme, this_, scan, open, expr, close);
215 ///////////////////////////////////////////////////////////////////////////////
216 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
218 }} // namespace boost::spirit