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