Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/boost/wave/grammars/cpp_expression_grammar.hpp @ 35

Last change on this file since 35 was 29, checked in by landauf, 17 years ago

updated boost from 1_33_1 to 1_34_1

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