Chris@16
|
1 /*=============================================================================
|
Chris@16
|
2 Boost.Wave: A Standard compliant C++ preprocessor library
|
Chris@16
|
3
|
Chris@16
|
4 http://www.boost.org/
|
Chris@16
|
5
|
Chris@16
|
6 Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost
|
Chris@16
|
7 Software License, Version 1.0. (See accompanying file
|
Chris@16
|
8 LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
9 =============================================================================*/
|
Chris@16
|
10
|
Chris@16
|
11 #if !defined(CPP_EXPRESSION_GRAMMAR_HPP_099CD1A4_A6C0_44BE_8F24_0B00F5BE5674_INCLUDED)
|
Chris@16
|
12 #define CPP_EXPRESSION_GRAMMAR_HPP_099CD1A4_A6C0_44BE_8F24_0B00F5BE5674_INCLUDED
|
Chris@16
|
13
|
Chris@16
|
14 #include <boost/wave/wave_config.hpp>
|
Chris@16
|
15
|
Chris@16
|
16 #include <boost/assert.hpp>
|
Chris@16
|
17 #include <boost/spirit/include/classic_core.hpp>
|
Chris@16
|
18 #include <boost/spirit/include/classic_closure.hpp>
|
Chris@16
|
19 #include <boost/spirit/include/classic_if.hpp>
|
Chris@16
|
20 #include <boost/spirit/include/classic_assign_actor.hpp>
|
Chris@16
|
21 #include <boost/spirit/include/classic_push_back_actor.hpp>
|
Chris@16
|
22
|
Chris@16
|
23 #include <boost/spirit/include/phoenix1_functions.hpp>
|
Chris@16
|
24 #include <boost/spirit/include/phoenix1_operators.hpp>
|
Chris@16
|
25 #include <boost/spirit/include/phoenix1_primitives.hpp>
|
Chris@16
|
26 #include <boost/spirit/include/phoenix1_statements.hpp>
|
Chris@16
|
27 #include <boost/spirit/include/phoenix1_casts.hpp>
|
Chris@16
|
28
|
Chris@16
|
29 #include <boost/wave/token_ids.hpp>
|
Chris@16
|
30
|
Chris@16
|
31 #include <boost/wave/cpp_exceptions.hpp>
|
Chris@16
|
32 #include <boost/wave/grammars/cpp_expression_grammar_gen.hpp>
|
Chris@16
|
33 #include <boost/wave/grammars/cpp_literal_grammar_gen.hpp>
|
Chris@16
|
34 #include <boost/wave/grammars/cpp_expression_value.hpp>
|
Chris@16
|
35 #include <boost/wave/util/pattern_parser.hpp>
|
Chris@16
|
36 #include <boost/wave/util/macro_helpers.hpp>
|
Chris@16
|
37
|
Chris@16
|
38 #if !defined(spirit_append_actor)
|
Chris@16
|
39 #define spirit_append_actor(actor) boost::spirit::classic::push_back_a(actor)
|
Chris@16
|
40 #define spirit_assign_actor(actor) boost::spirit::classic::assign_a(actor)
|
Chris@16
|
41 #endif // !defined(spirit_append_actor)
|
Chris@16
|
42
|
Chris@16
|
43 // this must occur after all of the includes and before any code appears
|
Chris@16
|
44 #ifdef BOOST_HAS_ABI_HEADERS
|
Chris@16
|
45 #include BOOST_ABI_PREFIX
|
Chris@16
|
46 #endif
|
Chris@16
|
47
|
Chris@16
|
48 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
49 //
|
Chris@16
|
50 // Encapsulation of the grammar for evaluation of constant preprocessor
|
Chris@16
|
51 // expressions
|
Chris@16
|
52 //
|
Chris@16
|
53 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
54 namespace boost {
|
Chris@16
|
55 namespace wave {
|
Chris@16
|
56 namespace grammars {
|
Chris@16
|
57 namespace closures {
|
Chris@16
|
58
|
Chris@16
|
59 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
60 //
|
Chris@16
|
61 // define the closure type used throughout the C++ expression grammar
|
Chris@16
|
62 //
|
Chris@16
|
63 // Throughout this grammar all literal tokens are stored into a
|
Chris@16
|
64 // closure_value variables, which converts the types appropriately, where
|
Chris@16
|
65 // required.
|
Chris@16
|
66 //
|
Chris@16
|
67 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
68 struct cpp_expr_closure
|
Chris@16
|
69 : boost::spirit::classic::closure<cpp_expr_closure, closure_value>
|
Chris@16
|
70 {
|
Chris@16
|
71 member1 val;
|
Chris@16
|
72 };
|
Chris@16
|
73
|
Chris@16
|
74 } // namespace closures
|
Chris@16
|
75
|
Chris@16
|
76 namespace impl {
|
Chris@16
|
77
|
Chris@16
|
78 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
79 //
|
Chris@16
|
80 // convert the given token value (integer literal) to a unsigned long
|
Chris@16
|
81 //
|
Chris@16
|
82 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
83 struct convert_intlit {
|
Chris@16
|
84
|
Chris@16
|
85 template <typename ArgT>
|
Chris@16
|
86 struct result {
|
Chris@16
|
87
|
Chris@16
|
88 typedef boost::wave::grammars::closures::closure_value type;
|
Chris@16
|
89 };
|
Chris@16
|
90
|
Chris@16
|
91 template <typename TokenT>
|
Chris@16
|
92 boost::wave::grammars::closures::closure_value
|
Chris@16
|
93 operator()(TokenT const &token) const
|
Chris@16
|
94 {
|
Chris@16
|
95 typedef boost::wave::grammars::closures::closure_value return_type;
|
Chris@16
|
96 bool is_unsigned = false;
|
Chris@16
|
97 uint_literal_type ul = intlit_grammar_gen<TokenT>::evaluate(token,
|
Chris@16
|
98 is_unsigned);
|
Chris@16
|
99
|
Chris@16
|
100 return is_unsigned ?
|
Chris@16
|
101 return_type(ul) : return_type(static_cast<int_literal_type>(ul));
|
Chris@16
|
102 }
|
Chris@16
|
103 };
|
Chris@16
|
104 phoenix::function<convert_intlit> const as_intlit;
|
Chris@16
|
105
|
Chris@16
|
106 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
107 //
|
Chris@16
|
108 // Convert the given token value (character literal) to a unsigned int
|
Chris@16
|
109 //
|
Chris@16
|
110 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
111 struct convert_chlit {
|
Chris@16
|
112
|
Chris@16
|
113 template <typename ArgT>
|
Chris@16
|
114 struct result {
|
Chris@16
|
115
|
Chris@16
|
116 typedef boost::wave::grammars::closures::closure_value type;
|
Chris@16
|
117 };
|
Chris@16
|
118
|
Chris@16
|
119 template <typename TokenT>
|
Chris@16
|
120 boost::wave::grammars::closures::closure_value
|
Chris@16
|
121 operator()(TokenT const &token) const
|
Chris@16
|
122 {
|
Chris@16
|
123 typedef boost::wave::grammars::closures::closure_value return_type;
|
Chris@16
|
124 value_error status = error_noerror;
|
Chris@16
|
125
|
Chris@16
|
126 // If the literal is a wchar_t and wchar_t is represented by a
|
Chris@16
|
127 // signed integral type, then the created value will be signed as
|
Chris@16
|
128 // well, otherwise we assume unsigned values.
|
Chris@16
|
129 #if BOOST_WAVE_WCHAR_T_SIGNEDNESS == BOOST_WAVE_WCHAR_T_AUTOSELECT
|
Chris@16
|
130 if ('L' == token.get_value()[0] && std::numeric_limits<wchar_t>::is_signed)
|
Chris@16
|
131 {
|
Chris@16
|
132 int value = chlit_grammar_gen<int, TokenT>::evaluate(token, status);
|
Chris@16
|
133 return return_type(value, status);
|
Chris@16
|
134 }
|
Chris@16
|
135 #elif BOOST_WAVE_WCHAR_T_SIGNEDNESS == BOOST_WAVE_WCHAR_T_FORCE_SIGNED
|
Chris@16
|
136 if ('L' == token.get_value()[0])
|
Chris@16
|
137 {
|
Chris@16
|
138 int value = chlit_grammar_gen<int, TokenT>::evaluate(token, status);
|
Chris@16
|
139 return return_type(value, status);
|
Chris@16
|
140 }
|
Chris@16
|
141 #endif
|
Chris@16
|
142
|
Chris@16
|
143 unsigned int value = chlit_grammar_gen<unsigned int, TokenT>::evaluate(token, status);
|
Chris@16
|
144 return return_type(value, status);
|
Chris@16
|
145 }
|
Chris@16
|
146 };
|
Chris@16
|
147 phoenix::function<convert_chlit> const as_chlit;
|
Chris@16
|
148
|
Chris@16
|
149 ////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
150 //
|
Chris@16
|
151 // Handle the ?: operator with correct type and error propagation
|
Chris@16
|
152 //
|
Chris@16
|
153 ////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
154 struct operator_questionmark {
|
Chris@16
|
155
|
Chris@16
|
156 template <typename CondT, typename Arg1T, typename Arg2T>
|
Chris@16
|
157 struct result {
|
Chris@16
|
158
|
Chris@16
|
159 typedef boost::wave::grammars::closures::closure_value type;
|
Chris@16
|
160 };
|
Chris@16
|
161
|
Chris@16
|
162 template <typename CondT, typename Arg1T, typename Arg2T>
|
Chris@16
|
163 boost::wave::grammars::closures::closure_value
|
Chris@16
|
164 operator()(CondT const &cond, Arg1T &val1, Arg2T const &val2) const
|
Chris@16
|
165 {
|
Chris@16
|
166 return val1.handle_questionmark(cond, val2);
|
Chris@16
|
167 }
|
Chris@16
|
168 };
|
Chris@16
|
169 phoenix::function<operator_questionmark> const questionmark;
|
Chris@16
|
170
|
Chris@16
|
171 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
172 //
|
Chris@16
|
173 // Handle type conversion conserving error conditions
|
Chris@16
|
174 //
|
Chris@16
|
175 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
176 struct operator_to_bool {
|
Chris@16
|
177
|
Chris@16
|
178 template <typename ArgT>
|
Chris@16
|
179 struct result {
|
Chris@16
|
180
|
Chris@16
|
181 typedef boost::wave::grammars::closures::closure_value type;
|
Chris@16
|
182 };
|
Chris@16
|
183
|
Chris@16
|
184 template <typename ArgT>
|
Chris@16
|
185 boost::wave::grammars::closures::closure_value
|
Chris@16
|
186 operator()(ArgT &val) const
|
Chris@16
|
187 {
|
Chris@16
|
188 typedef boost::wave::grammars::closures::closure_value return_type;
|
Chris@16
|
189 return return_type(
|
Chris@16
|
190 boost::wave::grammars::closures::as_bool(val), val.is_valid());
|
Chris@16
|
191 }
|
Chris@16
|
192 };
|
Chris@16
|
193 phoenix::function<operator_to_bool> const to_bool;
|
Chris@16
|
194
|
Chris@16
|
195 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
196 //
|
Chris@16
|
197 // Handle explicit type conversion
|
Chris@16
|
198 //
|
Chris@16
|
199 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
200 struct operator_as_bool {
|
Chris@16
|
201
|
Chris@16
|
202 template <typename ArgT>
|
Chris@16
|
203 struct result {
|
Chris@16
|
204
|
Chris@16
|
205 typedef bool type;
|
Chris@16
|
206 };
|
Chris@16
|
207
|
Chris@16
|
208 template <typename ArgT>
|
Chris@16
|
209 bool
|
Chris@16
|
210 operator()(ArgT &val) const
|
Chris@16
|
211 {
|
Chris@16
|
212 return boost::wave::grammars::closures::as_bool(val);
|
Chris@16
|
213 }
|
Chris@16
|
214 };
|
Chris@16
|
215 phoenix::function<operator_as_bool> const as_bool;
|
Chris@16
|
216
|
Chris@16
|
217 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
218 //
|
Chris@16
|
219 // Handle closure value operators with proper error propagation
|
Chris@16
|
220 //
|
Chris@16
|
221 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
222 #define BOOST_WAVE_BINARYOP(op, optok) \
|
Chris@16
|
223 struct operator_binary_ ## op { \
|
Chris@16
|
224 \
|
Chris@16
|
225 template <typename Arg1T, typename Arg2T> \
|
Chris@16
|
226 struct result { \
|
Chris@16
|
227 \
|
Chris@16
|
228 typedef boost::wave::grammars::closures::closure_value type; \
|
Chris@16
|
229 }; \
|
Chris@16
|
230 \
|
Chris@16
|
231 template <typename Arg1T, typename Arg2T> \
|
Chris@16
|
232 boost::wave::grammars::closures::closure_value \
|
Chris@16
|
233 operator()(Arg1T &val1, Arg2T &val2) const \
|
Chris@16
|
234 { \
|
Chris@16
|
235 return val1 optok val2; \
|
Chris@16
|
236 } \
|
Chris@16
|
237 }; \
|
Chris@16
|
238 phoenix::function<operator_binary_ ## op> const binary_ ## op \
|
Chris@16
|
239 /**/
|
Chris@16
|
240
|
Chris@16
|
241 BOOST_WAVE_BINARYOP(and, &&);
|
Chris@16
|
242 BOOST_WAVE_BINARYOP(or, ||);
|
Chris@16
|
243
|
Chris@16
|
244 BOOST_WAVE_BINARYOP(bitand, &);
|
Chris@16
|
245 BOOST_WAVE_BINARYOP(bitor, |);
|
Chris@16
|
246 BOOST_WAVE_BINARYOP(bitxor, ^);
|
Chris@16
|
247
|
Chris@16
|
248 BOOST_WAVE_BINARYOP(lesseq, <=);
|
Chris@16
|
249 BOOST_WAVE_BINARYOP(less, <);
|
Chris@16
|
250 BOOST_WAVE_BINARYOP(greater, >);
|
Chris@16
|
251 BOOST_WAVE_BINARYOP(greateq, >=);
|
Chris@16
|
252 BOOST_WAVE_BINARYOP(eq, ==);
|
Chris@16
|
253 BOOST_WAVE_BINARYOP(ne, !=);
|
Chris@16
|
254
|
Chris@16
|
255 #undef BOOST_WAVE_BINARYOP
|
Chris@16
|
256
|
Chris@16
|
257 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
258 #define BOOST_WAVE_UNARYOP(op, optok) \
|
Chris@16
|
259 struct operator_unary_ ## op { \
|
Chris@16
|
260 \
|
Chris@16
|
261 template <typename ArgT> \
|
Chris@16
|
262 struct result { \
|
Chris@16
|
263 \
|
Chris@16
|
264 typedef boost::wave::grammars::closures::closure_value type; \
|
Chris@16
|
265 }; \
|
Chris@16
|
266 \
|
Chris@16
|
267 template <typename ArgT> \
|
Chris@16
|
268 boost::wave::grammars::closures::closure_value \
|
Chris@16
|
269 operator()(ArgT &val) const \
|
Chris@16
|
270 { \
|
Chris@16
|
271 return optok val; \
|
Chris@16
|
272 } \
|
Chris@16
|
273 }; \
|
Chris@16
|
274 phoenix::function<operator_unary_ ## op> const unary_ ## op \
|
Chris@16
|
275 /**/
|
Chris@16
|
276
|
Chris@16
|
277 BOOST_WAVE_UNARYOP(neg, !);
|
Chris@16
|
278
|
Chris@16
|
279 #undef BOOST_WAVE_UNARYOP
|
Chris@16
|
280
|
Chris@16
|
281 } // namespace impl
|
Chris@16
|
282
|
Chris@16
|
283 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
284 // define, whether the rule's should generate some debug output
|
Chris@16
|
285 #define TRACE_CPP_EXPR_GRAMMAR \
|
Chris@16
|
286 bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_CPP_EXPR_GRAMMAR) \
|
Chris@16
|
287 /**/
|
Chris@16
|
288
|
Chris@16
|
289 struct expression_grammar :
|
Chris@16
|
290 public boost::spirit::classic::grammar<
|
Chris@16
|
291 expression_grammar,
|
Chris@16
|
292 closures::cpp_expr_closure::context_t
|
Chris@16
|
293 >
|
Chris@16
|
294 {
|
Chris@16
|
295 expression_grammar()
|
Chris@16
|
296 {
|
Chris@16
|
297 BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this, "expression_grammar",
|
Chris@16
|
298 TRACE_CPP_EXPR_GRAMMAR);
|
Chris@16
|
299 }
|
Chris@16
|
300
|
Chris@16
|
301 // no need for copy constructor/assignment operator
|
Chris@16
|
302 expression_grammar(expression_grammar const&);
|
Chris@16
|
303 expression_grammar& operator= (expression_grammar const&);
|
Chris@16
|
304
|
Chris@16
|
305 template <typename ScannerT>
|
Chris@16
|
306 struct definition
|
Chris@16
|
307 {
|
Chris@16
|
308 typedef closures::cpp_expr_closure closure_type;
|
Chris@16
|
309 typedef boost::spirit::classic::rule<ScannerT, closure_type::context_t> rule_t;
|
Chris@16
|
310 typedef boost::spirit::classic::rule<ScannerT> simple_rule_t;
|
Chris@16
|
311
|
Chris@16
|
312 simple_rule_t pp_expression;
|
Chris@16
|
313
|
Chris@16
|
314 rule_t const_exp;
|
Chris@16
|
315 rule_t logical_or_exp, logical_and_exp;
|
Chris@16
|
316 rule_t inclusive_or_exp, exclusive_or_exp, and_exp;
|
Chris@16
|
317 rule_t cmp_equality, cmp_relational;
|
Chris@16
|
318 rule_t shift_exp;
|
Chris@16
|
319 rule_t add_exp, multiply_exp;
|
Chris@16
|
320 rule_t unary_exp, primary_exp, constant;
|
Chris@16
|
321
|
Chris@16
|
322 rule_t const_exp_nocalc;
|
Chris@16
|
323 rule_t logical_or_exp_nocalc, logical_and_exp_nocalc;
|
Chris@16
|
324 rule_t inclusive_or_exp_nocalc, exclusive_or_exp_nocalc, and_exp_nocalc;
|
Chris@16
|
325 rule_t cmp_equality_nocalc, cmp_relational_nocalc;
|
Chris@16
|
326 rule_t shift_exp_nocalc;
|
Chris@16
|
327 rule_t add_exp_nocalc, multiply_exp_nocalc;
|
Chris@16
|
328 rule_t unary_exp_nocalc, primary_exp_nocalc, constant_nocalc;
|
Chris@16
|
329
|
Chris@16
|
330 boost::spirit::classic::subrule<0, closure_type::context_t> const_exp_subrule;
|
Chris@16
|
331
|
Chris@16
|
332 definition(expression_grammar const &self)
|
Chris@16
|
333 {
|
Chris@16
|
334 using namespace boost::spirit::classic;
|
Chris@16
|
335 using namespace phoenix;
|
Chris@16
|
336 using namespace boost::wave;
|
Chris@16
|
337 using boost::wave::util::pattern_p;
|
Chris@16
|
338
|
Chris@16
|
339 pp_expression
|
Chris@16
|
340 = const_exp[self.val = arg1]
|
Chris@16
|
341 ;
|
Chris@16
|
342
|
Chris@16
|
343 const_exp
|
Chris@16
|
344 = logical_or_exp[const_exp.val = arg1]
|
Chris@16
|
345 >> !(const_exp_subrule =
|
Chris@16
|
346 ch_p(T_QUESTION_MARK)
|
Chris@16
|
347 >> const_exp
|
Chris@16
|
348 [
|
Chris@16
|
349 const_exp_subrule.val = arg1
|
Chris@16
|
350 ]
|
Chris@16
|
351 >> ch_p(T_COLON)
|
Chris@16
|
352 >> const_exp
|
Chris@16
|
353 [
|
Chris@16
|
354 const_exp_subrule.val =
|
Chris@16
|
355 impl::questionmark(const_exp.val,
|
Chris@16
|
356 const_exp_subrule.val, arg1)
|
Chris@16
|
357 ]
|
Chris@16
|
358 )[const_exp.val = arg1]
|
Chris@16
|
359 ;
|
Chris@16
|
360
|
Chris@16
|
361 logical_or_exp
|
Chris@16
|
362 = logical_and_exp[logical_or_exp.val = arg1]
|
Chris@16
|
363 >> *( if_p(impl::as_bool(logical_or_exp.val))
|
Chris@16
|
364 [
|
Chris@16
|
365 // if one of the || operators is true, no more
|
Chris@16
|
366 // evaluation is required
|
Chris@16
|
367 pattern_p(T_OROR, MainTokenMask)
|
Chris@16
|
368 >> logical_and_exp_nocalc
|
Chris@16
|
369 [
|
Chris@16
|
370 logical_or_exp.val =
|
Chris@16
|
371 impl::to_bool(logical_or_exp.val)
|
Chris@16
|
372 ]
|
Chris@16
|
373 ]
|
Chris@16
|
374 .else_p
|
Chris@16
|
375 [
|
Chris@16
|
376 pattern_p(T_OROR, MainTokenMask)
|
Chris@16
|
377 >> logical_and_exp
|
Chris@16
|
378 [
|
Chris@16
|
379 logical_or_exp.val =
|
Chris@16
|
380 impl::binary_or(logical_or_exp.val, arg1)
|
Chris@16
|
381 ]
|
Chris@16
|
382 ]
|
Chris@16
|
383 )
|
Chris@16
|
384 ;
|
Chris@16
|
385
|
Chris@16
|
386 logical_and_exp
|
Chris@16
|
387 = inclusive_or_exp[logical_and_exp.val = arg1]
|
Chris@16
|
388 >> *( if_p(impl::as_bool(logical_and_exp.val))
|
Chris@16
|
389 [
|
Chris@16
|
390 pattern_p(T_ANDAND, MainTokenMask)
|
Chris@16
|
391 >> inclusive_or_exp
|
Chris@16
|
392 [
|
Chris@16
|
393 logical_and_exp.val =
|
Chris@16
|
394 impl::binary_and(logical_and_exp.val, arg1)
|
Chris@16
|
395 ]
|
Chris@16
|
396 ]
|
Chris@16
|
397 .else_p
|
Chris@16
|
398 [
|
Chris@16
|
399 // if one of the && operators is false, no more
|
Chris@16
|
400 // evaluation is required
|
Chris@16
|
401 pattern_p(T_ANDAND, MainTokenMask)
|
Chris@16
|
402 >> inclusive_or_exp_nocalc
|
Chris@16
|
403 [
|
Chris@16
|
404 logical_and_exp.val =
|
Chris@16
|
405 impl::to_bool(logical_and_exp.val)
|
Chris@16
|
406 ]
|
Chris@16
|
407 ]
|
Chris@16
|
408 )
|
Chris@16
|
409 ;
|
Chris@16
|
410
|
Chris@16
|
411 inclusive_or_exp
|
Chris@16
|
412 = exclusive_or_exp[inclusive_or_exp.val = arg1]
|
Chris@16
|
413 >> *( pattern_p(T_OR, MainTokenMask)
|
Chris@16
|
414 >> exclusive_or_exp
|
Chris@16
|
415 [
|
Chris@16
|
416 inclusive_or_exp.val =
|
Chris@16
|
417 impl::binary_bitor(inclusive_or_exp.val, arg1)
|
Chris@16
|
418 ]
|
Chris@16
|
419 )
|
Chris@16
|
420 ;
|
Chris@16
|
421
|
Chris@16
|
422 exclusive_or_exp
|
Chris@16
|
423 = and_exp[exclusive_or_exp.val = arg1]
|
Chris@16
|
424 >> *( pattern_p(T_XOR, MainTokenMask)
|
Chris@16
|
425 >> and_exp
|
Chris@16
|
426 [
|
Chris@16
|
427 exclusive_or_exp.val =
|
Chris@16
|
428 impl::binary_bitxor(exclusive_or_exp.val, arg1)
|
Chris@16
|
429 ]
|
Chris@16
|
430 )
|
Chris@16
|
431 ;
|
Chris@16
|
432
|
Chris@16
|
433 and_exp
|
Chris@16
|
434 = cmp_equality[and_exp.val = arg1]
|
Chris@16
|
435 >> *( pattern_p(T_AND, MainTokenMask)
|
Chris@16
|
436 >> cmp_equality
|
Chris@16
|
437 [
|
Chris@16
|
438 and_exp.val =
|
Chris@16
|
439 impl::binary_bitand(and_exp.val, arg1)
|
Chris@16
|
440 ]
|
Chris@16
|
441 )
|
Chris@16
|
442 ;
|
Chris@16
|
443
|
Chris@16
|
444 cmp_equality
|
Chris@16
|
445 = cmp_relational[cmp_equality.val = arg1]
|
Chris@16
|
446 >> *( ch_p(T_EQUAL)
|
Chris@16
|
447 >> cmp_relational
|
Chris@16
|
448 [
|
Chris@16
|
449 cmp_equality.val =
|
Chris@16
|
450 impl::binary_eq(cmp_equality.val, arg1)
|
Chris@16
|
451 ]
|
Chris@16
|
452 | pattern_p(T_NOTEQUAL, MainTokenMask)
|
Chris@16
|
453 >> cmp_relational
|
Chris@16
|
454 [
|
Chris@16
|
455 cmp_equality.val =
|
Chris@16
|
456 impl::binary_ne(cmp_equality.val, arg1)
|
Chris@16
|
457 ]
|
Chris@16
|
458 )
|
Chris@16
|
459 ;
|
Chris@16
|
460
|
Chris@16
|
461 cmp_relational
|
Chris@16
|
462 = shift_exp[cmp_relational.val = arg1]
|
Chris@16
|
463 >> *( ch_p(T_LESSEQUAL)
|
Chris@16
|
464 >> shift_exp
|
Chris@16
|
465 [
|
Chris@16
|
466 cmp_relational.val =
|
Chris@16
|
467 impl::binary_lesseq(cmp_relational.val, arg1)
|
Chris@16
|
468 ]
|
Chris@16
|
469 | ch_p(T_GREATEREQUAL)
|
Chris@16
|
470 >> shift_exp
|
Chris@16
|
471 [
|
Chris@16
|
472 cmp_relational.val =
|
Chris@16
|
473 impl::binary_greateq(cmp_relational.val, arg1)
|
Chris@16
|
474 ]
|
Chris@16
|
475 | ch_p(T_LESS)
|
Chris@16
|
476 >> shift_exp
|
Chris@16
|
477 [
|
Chris@16
|
478 cmp_relational.val =
|
Chris@16
|
479 impl::binary_less(cmp_relational.val, arg1)
|
Chris@16
|
480 ]
|
Chris@16
|
481 | ch_p(T_GREATER)
|
Chris@16
|
482 >> shift_exp
|
Chris@16
|
483 [
|
Chris@16
|
484 cmp_relational.val =
|
Chris@16
|
485 impl::binary_greater(cmp_relational.val, arg1)
|
Chris@16
|
486 ]
|
Chris@16
|
487 )
|
Chris@16
|
488 ;
|
Chris@16
|
489
|
Chris@16
|
490 shift_exp
|
Chris@16
|
491 = add_exp[shift_exp.val = arg1]
|
Chris@16
|
492 >> *( ch_p(T_SHIFTLEFT)
|
Chris@16
|
493 >> add_exp
|
Chris@16
|
494 [
|
Chris@16
|
495 shift_exp.val <<= arg1
|
Chris@16
|
496 ]
|
Chris@16
|
497 | ch_p(T_SHIFTRIGHT)
|
Chris@16
|
498 >> add_exp
|
Chris@16
|
499 [
|
Chris@16
|
500 shift_exp.val >>= arg1
|
Chris@16
|
501 ]
|
Chris@16
|
502 )
|
Chris@16
|
503 ;
|
Chris@16
|
504
|
Chris@16
|
505 add_exp
|
Chris@16
|
506 = multiply_exp[add_exp.val = arg1]
|
Chris@16
|
507 >> *( ch_p(T_PLUS)
|
Chris@16
|
508 >> multiply_exp
|
Chris@16
|
509 [
|
Chris@16
|
510 add_exp.val += arg1
|
Chris@16
|
511 ]
|
Chris@16
|
512 | ch_p(T_MINUS)
|
Chris@16
|
513 >> multiply_exp
|
Chris@16
|
514 [
|
Chris@16
|
515 add_exp.val -= arg1
|
Chris@16
|
516 ]
|
Chris@16
|
517 )
|
Chris@16
|
518 ;
|
Chris@16
|
519
|
Chris@16
|
520 multiply_exp
|
Chris@16
|
521 = unary_exp[multiply_exp.val = arg1]
|
Chris@16
|
522 >> *( ch_p(T_STAR)
|
Chris@16
|
523 >> unary_exp
|
Chris@16
|
524 [
|
Chris@16
|
525 multiply_exp.val *= arg1
|
Chris@16
|
526 ]
|
Chris@16
|
527 | ch_p(T_DIVIDE)
|
Chris@16
|
528 >> unary_exp
|
Chris@16
|
529 [
|
Chris@16
|
530 multiply_exp.val /= arg1
|
Chris@16
|
531 ]
|
Chris@16
|
532 | ch_p(T_PERCENT)
|
Chris@16
|
533 >> unary_exp
|
Chris@16
|
534 [
|
Chris@16
|
535 multiply_exp.val %= arg1
|
Chris@16
|
536 ]
|
Chris@16
|
537 )
|
Chris@16
|
538 ;
|
Chris@16
|
539
|
Chris@16
|
540 unary_exp
|
Chris@16
|
541 = primary_exp[unary_exp.val = arg1]
|
Chris@16
|
542 | ch_p(T_PLUS) >> unary_exp
|
Chris@16
|
543 [
|
Chris@16
|
544 unary_exp.val = arg1
|
Chris@16
|
545 ]
|
Chris@16
|
546 | ch_p(T_MINUS) >> unary_exp
|
Chris@16
|
547 [
|
Chris@16
|
548 unary_exp.val = -arg1
|
Chris@16
|
549 ]
|
Chris@16
|
550 | pattern_p(T_COMPL, MainTokenMask) >> unary_exp
|
Chris@16
|
551 [
|
Chris@16
|
552 unary_exp.val = ~arg1
|
Chris@16
|
553 ]
|
Chris@16
|
554 | pattern_p(T_NOT, MainTokenMask) >> unary_exp
|
Chris@16
|
555 [
|
Chris@16
|
556 unary_exp.val = impl::unary_neg(arg1)
|
Chris@16
|
557 ]
|
Chris@16
|
558 ;
|
Chris@16
|
559
|
Chris@16
|
560 primary_exp
|
Chris@16
|
561 = constant[primary_exp.val = arg1]
|
Chris@16
|
562 | ch_p(T_LEFTPAREN)
|
Chris@16
|
563 >> const_exp[primary_exp.val = arg1]
|
Chris@16
|
564 >> ch_p(T_RIGHTPAREN)
|
Chris@16
|
565 ;
|
Chris@16
|
566
|
Chris@16
|
567 constant
|
Chris@16
|
568 = ch_p(T_PP_NUMBER)
|
Chris@16
|
569 [
|
Chris@16
|
570 constant.val = impl::as_intlit(arg1)
|
Chris@16
|
571 ]
|
Chris@16
|
572 | ch_p(T_INTLIT)
|
Chris@16
|
573 [
|
Chris@16
|
574 constant.val = impl::as_intlit(arg1)
|
Chris@16
|
575 ]
|
Chris@16
|
576 | ch_p(T_CHARLIT)
|
Chris@16
|
577 [
|
Chris@16
|
578 constant.val = impl::as_chlit(arg1)
|
Chris@16
|
579 ]
|
Chris@16
|
580 ;
|
Chris@16
|
581
|
Chris@16
|
582 // here follows the same grammar, but without any embedded
|
Chris@16
|
583 // calculations
|
Chris@16
|
584 const_exp_nocalc
|
Chris@16
|
585 = logical_or_exp_nocalc
|
Chris@16
|
586 >> !( ch_p(T_QUESTION_MARK)
|
Chris@16
|
587 >> const_exp_nocalc
|
Chris@16
|
588 >> ch_p(T_COLON)
|
Chris@16
|
589 >> const_exp_nocalc
|
Chris@16
|
590 )
|
Chris@16
|
591 ;
|
Chris@16
|
592
|
Chris@16
|
593 logical_or_exp_nocalc
|
Chris@16
|
594 = logical_and_exp_nocalc
|
Chris@16
|
595 >> *( pattern_p(T_OROR, MainTokenMask)
|
Chris@16
|
596 >> logical_and_exp_nocalc
|
Chris@16
|
597 )
|
Chris@16
|
598 ;
|
Chris@16
|
599
|
Chris@16
|
600 logical_and_exp_nocalc
|
Chris@16
|
601 = inclusive_or_exp_nocalc
|
Chris@16
|
602 >> *( pattern_p(T_ANDAND, MainTokenMask)
|
Chris@16
|
603 >> inclusive_or_exp_nocalc
|
Chris@16
|
604 )
|
Chris@16
|
605 ;
|
Chris@16
|
606
|
Chris@16
|
607 inclusive_or_exp_nocalc
|
Chris@16
|
608 = exclusive_or_exp_nocalc
|
Chris@16
|
609 >> *( pattern_p(T_OR, MainTokenMask)
|
Chris@16
|
610 >> exclusive_or_exp_nocalc
|
Chris@16
|
611 )
|
Chris@16
|
612 ;
|
Chris@16
|
613
|
Chris@16
|
614 exclusive_or_exp_nocalc
|
Chris@16
|
615 = and_exp_nocalc
|
Chris@16
|
616 >> *( pattern_p(T_XOR, MainTokenMask)
|
Chris@16
|
617 >> and_exp_nocalc
|
Chris@16
|
618 )
|
Chris@16
|
619 ;
|
Chris@16
|
620
|
Chris@16
|
621 and_exp_nocalc
|
Chris@16
|
622 = cmp_equality_nocalc
|
Chris@16
|
623 >> *( pattern_p(T_AND, MainTokenMask)
|
Chris@16
|
624 >> cmp_equality_nocalc
|
Chris@16
|
625 )
|
Chris@16
|
626 ;
|
Chris@16
|
627
|
Chris@16
|
628 cmp_equality_nocalc
|
Chris@16
|
629 = cmp_relational_nocalc
|
Chris@16
|
630 >> *( ch_p(T_EQUAL)
|
Chris@16
|
631 >> cmp_relational_nocalc
|
Chris@16
|
632 | pattern_p(T_NOTEQUAL, MainTokenMask)
|
Chris@16
|
633 >> cmp_relational_nocalc
|
Chris@16
|
634 )
|
Chris@16
|
635 ;
|
Chris@16
|
636
|
Chris@16
|
637 cmp_relational_nocalc
|
Chris@16
|
638 = shift_exp_nocalc
|
Chris@16
|
639 >> *( ch_p(T_LESSEQUAL)
|
Chris@16
|
640 >> shift_exp_nocalc
|
Chris@16
|
641 | ch_p(T_GREATEREQUAL)
|
Chris@16
|
642 >> shift_exp_nocalc
|
Chris@16
|
643 | ch_p(T_LESS)
|
Chris@16
|
644 >> shift_exp_nocalc
|
Chris@16
|
645 | ch_p(T_GREATER)
|
Chris@16
|
646 >> shift_exp_nocalc
|
Chris@16
|
647 )
|
Chris@16
|
648 ;
|
Chris@16
|
649
|
Chris@16
|
650 shift_exp_nocalc
|
Chris@16
|
651 = add_exp_nocalc
|
Chris@16
|
652 >> *( ch_p(T_SHIFTLEFT)
|
Chris@16
|
653 >> add_exp_nocalc
|
Chris@16
|
654 | ch_p(T_SHIFTRIGHT)
|
Chris@16
|
655 >> add_exp_nocalc
|
Chris@16
|
656 )
|
Chris@16
|
657 ;
|
Chris@16
|
658
|
Chris@16
|
659 add_exp_nocalc
|
Chris@16
|
660 = multiply_exp_nocalc
|
Chris@16
|
661 >> *( ch_p(T_PLUS)
|
Chris@16
|
662 >> multiply_exp_nocalc
|
Chris@16
|
663 | ch_p(T_MINUS)
|
Chris@16
|
664 >> multiply_exp_nocalc
|
Chris@16
|
665 )
|
Chris@16
|
666 ;
|
Chris@16
|
667
|
Chris@16
|
668 multiply_exp_nocalc
|
Chris@16
|
669 = unary_exp_nocalc
|
Chris@16
|
670 >> *( ch_p(T_STAR)
|
Chris@16
|
671 >> unary_exp_nocalc
|
Chris@16
|
672 | ch_p(T_DIVIDE)
|
Chris@16
|
673 >> unary_exp_nocalc
|
Chris@16
|
674 | ch_p(T_PERCENT)
|
Chris@16
|
675 >> unary_exp_nocalc
|
Chris@16
|
676 )
|
Chris@16
|
677 ;
|
Chris@16
|
678
|
Chris@16
|
679 unary_exp_nocalc
|
Chris@16
|
680 = primary_exp_nocalc
|
Chris@16
|
681 | ch_p(T_PLUS) >> unary_exp_nocalc
|
Chris@16
|
682 | ch_p(T_MINUS) >> unary_exp_nocalc
|
Chris@16
|
683 | pattern_p(T_COMPL, MainTokenMask) >> unary_exp_nocalc
|
Chris@16
|
684 | pattern_p(T_NOT, MainTokenMask) >> unary_exp_nocalc
|
Chris@16
|
685 ;
|
Chris@16
|
686
|
Chris@16
|
687 primary_exp_nocalc
|
Chris@16
|
688 = constant_nocalc
|
Chris@16
|
689 | ch_p(T_LEFTPAREN)
|
Chris@16
|
690 >> const_exp_nocalc
|
Chris@16
|
691 >> ch_p(T_RIGHTPAREN)
|
Chris@16
|
692 ;
|
Chris@16
|
693
|
Chris@16
|
694 constant_nocalc
|
Chris@16
|
695 = ch_p(T_PP_NUMBER)
|
Chris@16
|
696 | ch_p(T_INTLIT)
|
Chris@16
|
697 | ch_p(T_CHARLIT)
|
Chris@16
|
698 ;
|
Chris@16
|
699
|
Chris@16
|
700 BOOST_SPIRIT_DEBUG_TRACE_RULE(pp_expression, TRACE_CPP_EXPR_GRAMMAR);
|
Chris@16
|
701 BOOST_SPIRIT_DEBUG_TRACE_RULE(const_exp, TRACE_CPP_EXPR_GRAMMAR);
|
Chris@16
|
702 BOOST_SPIRIT_DEBUG_TRACE_RULE(logical_or_exp, TRACE_CPP_EXPR_GRAMMAR);
|
Chris@16
|
703 BOOST_SPIRIT_DEBUG_TRACE_RULE(logical_and_exp, TRACE_CPP_EXPR_GRAMMAR);
|
Chris@16
|
704 BOOST_SPIRIT_DEBUG_TRACE_RULE(inclusive_or_exp, TRACE_CPP_EXPR_GRAMMAR);
|
Chris@16
|
705 BOOST_SPIRIT_DEBUG_TRACE_RULE(exclusive_or_exp, TRACE_CPP_EXPR_GRAMMAR);
|
Chris@16
|
706 BOOST_SPIRIT_DEBUG_TRACE_RULE(and_exp, TRACE_CPP_EXPR_GRAMMAR);
|
Chris@16
|
707 BOOST_SPIRIT_DEBUG_TRACE_RULE(cmp_equality, TRACE_CPP_EXPR_GRAMMAR);
|
Chris@16
|
708 BOOST_SPIRIT_DEBUG_TRACE_RULE(cmp_relational, TRACE_CPP_EXPR_GRAMMAR);
|
Chris@16
|
709 BOOST_SPIRIT_DEBUG_TRACE_RULE(shift_exp, TRACE_CPP_EXPR_GRAMMAR);
|
Chris@16
|
710 BOOST_SPIRIT_DEBUG_TRACE_RULE(add_exp, TRACE_CPP_EXPR_GRAMMAR);
|
Chris@16
|
711 BOOST_SPIRIT_DEBUG_TRACE_RULE(multiply_exp, TRACE_CPP_EXPR_GRAMMAR);
|
Chris@16
|
712 BOOST_SPIRIT_DEBUG_TRACE_RULE(unary_exp, TRACE_CPP_EXPR_GRAMMAR);
|
Chris@16
|
713 BOOST_SPIRIT_DEBUG_TRACE_RULE(primary_exp, TRACE_CPP_EXPR_GRAMMAR);
|
Chris@16
|
714 BOOST_SPIRIT_DEBUG_TRACE_RULE(constant, TRACE_CPP_EXPR_GRAMMAR);
|
Chris@16
|
715 BOOST_SPIRIT_DEBUG_TRACE_RULE(const_exp_subrule, TRACE_CPP_EXPR_GRAMMAR);
|
Chris@16
|
716
|
Chris@16
|
717 BOOST_SPIRIT_DEBUG_TRACE_RULE(const_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
Chris@16
|
718 BOOST_SPIRIT_DEBUG_TRACE_RULE(logical_or_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
Chris@16
|
719 BOOST_SPIRIT_DEBUG_TRACE_RULE(logical_and_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
Chris@16
|
720 BOOST_SPIRIT_DEBUG_TRACE_RULE(inclusive_or_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
Chris@16
|
721 BOOST_SPIRIT_DEBUG_TRACE_RULE(exclusive_or_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
Chris@16
|
722 BOOST_SPIRIT_DEBUG_TRACE_RULE(and_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
Chris@16
|
723 BOOST_SPIRIT_DEBUG_TRACE_RULE(cmp_equality_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
Chris@16
|
724 BOOST_SPIRIT_DEBUG_TRACE_RULE(cmp_relational_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
Chris@16
|
725 BOOST_SPIRIT_DEBUG_TRACE_RULE(shift_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
Chris@16
|
726 BOOST_SPIRIT_DEBUG_TRACE_RULE(add_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
Chris@16
|
727 BOOST_SPIRIT_DEBUG_TRACE_RULE(multiply_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
Chris@16
|
728 BOOST_SPIRIT_DEBUG_TRACE_RULE(unary_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
Chris@16
|
729 BOOST_SPIRIT_DEBUG_TRACE_RULE(primary_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
Chris@16
|
730 BOOST_SPIRIT_DEBUG_TRACE_RULE(constant_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
Chris@16
|
731 }
|
Chris@16
|
732
|
Chris@16
|
733 // start rule of this grammar
|
Chris@16
|
734 simple_rule_t const& start() const
|
Chris@16
|
735 { return pp_expression; }
|
Chris@16
|
736 };
|
Chris@16
|
737 };
|
Chris@16
|
738
|
Chris@16
|
739 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
740 #undef TRACE_CPP_EXPR_GRAMMAR
|
Chris@16
|
741
|
Chris@16
|
742 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
743 //
|
Chris@16
|
744 // The following function is defined here, to allow the separation of
|
Chris@16
|
745 // the compilation of the expression_grammar from the function using it.
|
Chris@16
|
746 //
|
Chris@16
|
747 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
748
|
Chris@16
|
749 #if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
|
Chris@16
|
750 #define BOOST_WAVE_EXPRGRAMMAR_GEN_INLINE
|
Chris@16
|
751 #else
|
Chris@16
|
752 #define BOOST_WAVE_EXPRGRAMMAR_GEN_INLINE inline
|
Chris@16
|
753 #endif
|
Chris@16
|
754
|
Chris@16
|
755 template <typename TokenT>
|
Chris@16
|
756 BOOST_WAVE_EXPRGRAMMAR_GEN_INLINE
|
Chris@16
|
757 bool
|
Chris@16
|
758 expression_grammar_gen<TokenT>::evaluate(
|
Chris@16
|
759 typename token_sequence_type::const_iterator const &first,
|
Chris@16
|
760 typename token_sequence_type::const_iterator const &last,
|
Chris@16
|
761 typename token_type::position_type const &act_pos,
|
Chris@16
|
762 bool if_block_status, value_error &status)
|
Chris@16
|
763 {
|
Chris@16
|
764 using namespace boost::spirit::classic;
|
Chris@16
|
765 using namespace boost::wave;
|
Chris@16
|
766 using namespace boost::wave::grammars::closures;
|
Chris@16
|
767
|
Chris@16
|
768 using boost::wave::util::impl::as_string;
|
Chris@16
|
769
|
Chris@16
|
770 typedef typename token_sequence_type::const_iterator iterator_type;
|
Chris@16
|
771 typedef typename token_sequence_type::value_type::string_type string_type;
|
Chris@16
|
772
|
Chris@16
|
773 parse_info<iterator_type> hit(first);
|
Chris@16
|
774 closure_value result; // expression result
|
Chris@16
|
775
|
Chris@16
|
776 #if !defined(BOOST_NO_EXCEPTIONS)
|
Chris@16
|
777 try
|
Chris@16
|
778 #endif
|
Chris@16
|
779 {
|
Chris@16
|
780 expression_grammar g; // expression grammar
|
Chris@16
|
781 hit = parse (first, last, g[spirit_assign_actor(result)],
|
Chris@16
|
782 ch_p(T_SPACE) | ch_p(T_CCOMMENT) | ch_p(T_CPPCOMMENT));
|
Chris@16
|
783
|
Chris@16
|
784 if (!hit.hit) {
|
Chris@16
|
785 // expression is illformed
|
Chris@16
|
786 if (if_block_status) {
|
Chris@16
|
787 string_type expression = as_string<string_type>(first, last);
|
Chris@16
|
788 if (0 == expression.size())
|
Chris@16
|
789 expression = "<empty expression>";
|
Chris@16
|
790 BOOST_WAVE_THROW(preprocess_exception, ill_formed_expression,
|
Chris@16
|
791 expression.c_str(), act_pos);
|
Chris@16
|
792 return false;
|
Chris@16
|
793 }
|
Chris@16
|
794 else {
|
Chris@16
|
795 // as the if_block_status is false no errors will be reported
|
Chris@16
|
796 return false;
|
Chris@16
|
797 }
|
Chris@16
|
798 }
|
Chris@16
|
799 }
|
Chris@16
|
800 #if !defined(BOOST_NO_EXCEPTIONS)
|
Chris@16
|
801 catch (boost::wave::preprocess_exception const& e) {
|
Chris@16
|
802 // expression is illformed
|
Chris@16
|
803 if (if_block_status) {
|
Chris@16
|
804 boost::throw_exception(e);
|
Chris@16
|
805 return false;
|
Chris@16
|
806 }
|
Chris@16
|
807 else {
|
Chris@16
|
808 // as the if_block_status is false no errors will be reported
|
Chris@16
|
809 return false;
|
Chris@16
|
810 }
|
Chris@16
|
811 }
|
Chris@16
|
812 #endif
|
Chris@16
|
813
|
Chris@16
|
814 if (!hit.full) {
|
Chris@16
|
815 // The token list starts with a valid expression, but there remains
|
Chris@16
|
816 // something. If the remainder consists out of whitespace only, the
|
Chris@16
|
817 // expression is still valid.
|
Chris@16
|
818 iterator_type next = hit.stop;
|
Chris@16
|
819
|
Chris@16
|
820 while (next != last) {
|
Chris@16
|
821 switch (static_cast<unsigned int>(token_id(*next))) {
|
Chris@16
|
822 case T_SPACE:
|
Chris@16
|
823 case T_SPACE2:
|
Chris@16
|
824 case T_CCOMMENT:
|
Chris@16
|
825 break; // ok continue
|
Chris@16
|
826
|
Chris@16
|
827 case T_NEWLINE:
|
Chris@16
|
828 case T_EOF:
|
Chris@16
|
829 case T_CPPCOMMENT: // contains newline
|
Chris@16
|
830 return as_bool(result); // expression is valid
|
Chris@16
|
831
|
Chris@16
|
832 default:
|
Chris@16
|
833 // expression is illformed
|
Chris@16
|
834 if (if_block_status) {
|
Chris@16
|
835 string_type expression = as_string<string_type>(first, last);
|
Chris@16
|
836 if (0 == expression.size())
|
Chris@16
|
837 expression = "<empty expression>";
|
Chris@16
|
838 BOOST_WAVE_THROW(preprocess_exception, ill_formed_expression,
|
Chris@16
|
839 expression.c_str(), act_pos);
|
Chris@16
|
840 return false;
|
Chris@16
|
841 }
|
Chris@16
|
842 else {
|
Chris@16
|
843 // as the if_block_status is false no errors will be reported
|
Chris@16
|
844 return false;
|
Chris@16
|
845 }
|
Chris@16
|
846 }
|
Chris@16
|
847 ++next;
|
Chris@16
|
848 }
|
Chris@16
|
849 }
|
Chris@16
|
850
|
Chris@16
|
851 if (error_noerror != result.is_valid()) // division or other error by zero occurred
|
Chris@16
|
852 status = result.is_valid();
|
Chris@16
|
853
|
Chris@16
|
854 // token sequence is a valid expression
|
Chris@16
|
855 return as_bool(result);
|
Chris@16
|
856 }
|
Chris@16
|
857
|
Chris@16
|
858 #undef BOOST_WAVE_EXPRGRAMMAR_GEN_INLINE
|
Chris@16
|
859
|
Chris@16
|
860 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
861 } // namespace grammars
|
Chris@16
|
862 } // namespace wave
|
Chris@16
|
863 } // namespace boost
|
Chris@16
|
864
|
Chris@16
|
865 // the suffix header occurs after all of the code
|
Chris@16
|
866 #ifdef BOOST_HAS_ABI_HEADERS
|
Chris@16
|
867 #include BOOST_ABI_SUFFIX
|
Chris@16
|
868 #endif
|
Chris@16
|
869
|
Chris@16
|
870 #endif // !defined(CPP_EXPRESSION_GRAMMAR_HPP_099CD1A4_A6C0_44BE_8F24_0B00F5BE5674_INCLUDED)
|