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