Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:39

0001 /*=============================================================================
0002     Boost.Wave: A Standard compliant C++ preprocessor library
0003 
0004     http://www.boost.org/
0005 
0006     Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost
0007     Software License, Version 1.0. (See accompanying file
0008     LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0009 =============================================================================*/
0010 
0011 #if !defined(BOOST_CPP_EXPRESSION_GRAMMAR_HPP_099CD1A4_A6C0_44BE_8F24_0B00F5BE5674_INCLUDED)
0012 #define BOOST_CPP_EXPRESSION_GRAMMAR_HPP_099CD1A4_A6C0_44BE_8F24_0B00F5BE5674_INCLUDED
0013 
0014 #include <boost/wave/wave_config.hpp>
0015 
0016 #include <boost/assert.hpp>
0017 #include <boost/spirit/include/classic_core.hpp>
0018 #include <boost/spirit/include/classic_closure.hpp>
0019 #include <boost/spirit/include/classic_if.hpp>
0020 #include <boost/spirit/include/classic_assign_actor.hpp>
0021 #include <boost/spirit/include/classic_push_back_actor.hpp>
0022 
0023 #include <boost/spirit/include/phoenix1_functions.hpp>
0024 #include <boost/spirit/include/phoenix1_operators.hpp>
0025 #include <boost/spirit/include/phoenix1_primitives.hpp>
0026 #include <boost/spirit/include/phoenix1_statements.hpp>
0027 #include <boost/spirit/include/phoenix1_casts.hpp>
0028 
0029 #include <boost/wave/token_ids.hpp>
0030 
0031 #include <boost/wave/cpp_exceptions.hpp>
0032 #include <boost/wave/grammars/cpp_expression_grammar_gen.hpp>
0033 #include <boost/wave/grammars/cpp_literal_grammar_gen.hpp>
0034 #include <boost/wave/grammars/cpp_expression_value.hpp>
0035 #include <boost/wave/util/pattern_parser.hpp>
0036 #include <boost/wave/util/macro_helpers.hpp>
0037 
0038 #if !defined(spirit_append_actor)
0039 #define spirit_append_actor(actor) boost::spirit::classic::push_back_a(actor)
0040 #define spirit_assign_actor(actor) boost::spirit::classic::assign_a(actor)
0041 #endif // !defined(spirit_append_actor)
0042 
0043 // this must occur after all of the includes and before any code appears
0044 #ifdef BOOST_HAS_ABI_HEADERS
0045 #include BOOST_ABI_PREFIX
0046 #endif
0047 
0048 ///////////////////////////////////////////////////////////////////////////////
0049 //
0050 //  Encapsulation of the grammar for evaluation of constant preprocessor
0051 //  expressions
0052 //
0053 ///////////////////////////////////////////////////////////////////////////////
0054 namespace boost {
0055 namespace wave {
0056 namespace grammars {
0057 namespace closures {
0058 
0059 ///////////////////////////////////////////////////////////////////////////////
0060 //
0061 //  define the closure type used throughout the C++ expression grammar
0062 //
0063 //      Throughout this grammar all literal tokens are stored into a
0064 //      closure_value variables, which converts the types appropriately, where
0065 //      required.
0066 //
0067 ///////////////////////////////////////////////////////////////////////////////
0068     struct cpp_expr_closure
0069     :   boost::spirit::classic::closure<cpp_expr_closure, closure_value>
0070     {
0071         member1 val;
0072     };
0073 
0074 }   // namespace closures
0075 
0076 namespace impl {
0077 
0078 ///////////////////////////////////////////////////////////////////////////////
0079 //
0080 //  convert the given token value (integer literal) to a unsigned long
0081 //
0082 ///////////////////////////////////////////////////////////////////////////////
0083     struct convert_intlit {
0084 
0085         template <typename ArgT>
0086         struct result {
0087 
0088             typedef boost::wave::grammars::closures::closure_value type;
0089         };
0090 
0091         template <typename TokenT>
0092         boost::wave::grammars::closures::closure_value
0093         operator()(TokenT const &token) const
0094         {
0095             typedef boost::wave::grammars::closures::closure_value return_type;
0096             bool is_unsigned = false;
0097             uint_literal_type ul = intlit_grammar_gen<TokenT>::evaluate(token,
0098                 is_unsigned);
0099 
0100             return is_unsigned ?
0101                 return_type(ul) : return_type(static_cast<int_literal_type>(ul));
0102         }
0103     };
0104     phoenix::function<convert_intlit> const as_intlit;
0105 
0106 ///////////////////////////////////////////////////////////////////////////////
0107 //
0108 //  Convert the given token value (character literal) to a unsigned int
0109 //
0110 ///////////////////////////////////////////////////////////////////////////////
0111     struct convert_chlit {
0112 
0113         template <typename ArgT>
0114         struct result {
0115 
0116             typedef boost::wave::grammars::closures::closure_value type;
0117         };
0118 
0119         template <typename TokenT>
0120         boost::wave::grammars::closures::closure_value
0121         operator()(TokenT const &token) const
0122         {
0123             typedef boost::wave::grammars::closures::closure_value return_type;
0124             value_error status = error_noerror;
0125 
0126             //  If the literal is a wchar_t and wchar_t is represented by a
0127             //  signed integral type, then the created value will be signed as
0128             //  well, otherwise we assume unsigned values.
0129 #if BOOST_WAVE_WCHAR_T_SIGNEDNESS == BOOST_WAVE_WCHAR_T_AUTOSELECT
0130             if ('L' == token.get_value()[0] && std::numeric_limits<wchar_t>::is_signed)
0131             {
0132                 int value = chlit_grammar_gen<int, TokenT>::evaluate(token, status);
0133                 return return_type(value, status);
0134             }
0135 #elif BOOST_WAVE_WCHAR_T_SIGNEDNESS == BOOST_WAVE_WCHAR_T_FORCE_SIGNED
0136             if ('L' == token.get_value()[0])
0137             {
0138                 int value = chlit_grammar_gen<int, TokenT>::evaluate(token, status);
0139                 return return_type(value, status);
0140             }
0141 #endif
0142 
0143             unsigned int value = chlit_grammar_gen<unsigned int, TokenT>::evaluate(token, status);
0144             return return_type(value, status);
0145         }
0146     };
0147     phoenix::function<convert_chlit> const as_chlit;
0148 
0149 ////////////////////////////////////////////////////////////////////////////////
0150 //
0151 //  Handle the ?: operator with correct type and error propagation
0152 //
0153 ////////////////////////////////////////////////////////////////////////////////
0154     struct operator_questionmark {
0155 
0156         template <typename CondT, typename Arg1T, typename Arg2T>
0157         struct result {
0158 
0159             typedef boost::wave::grammars::closures::closure_value type;
0160         };
0161 
0162         template <typename CondT, typename Arg1T, typename Arg2T>
0163         boost::wave::grammars::closures::closure_value
0164         operator()(CondT const &cond, Arg1T &val1, Arg2T const &val2) const
0165         {
0166             return val1.handle_questionmark(cond, val2);
0167         }
0168     };
0169     phoenix::function<operator_questionmark> const questionmark;
0170 
0171 ///////////////////////////////////////////////////////////////////////////////
0172 //
0173 //  Handle type conversion conserving error conditions
0174 //
0175 ///////////////////////////////////////////////////////////////////////////////
0176     struct operator_to_bool {
0177 
0178         template <typename ArgT>
0179         struct result {
0180 
0181             typedef boost::wave::grammars::closures::closure_value type;
0182         };
0183 
0184         template <typename ArgT>
0185         boost::wave::grammars::closures::closure_value
0186         operator()(ArgT &val) const
0187         {
0188             typedef boost::wave::grammars::closures::closure_value return_type;
0189             return return_type(
0190                 boost::wave::grammars::closures::as_bool(val), val.is_valid());
0191         }
0192     };
0193     phoenix::function<operator_to_bool> const to_bool;
0194 
0195 ///////////////////////////////////////////////////////////////////////////////
0196 //
0197 //  Handle explicit type conversion
0198 //
0199 ///////////////////////////////////////////////////////////////////////////////
0200     struct operator_as_bool {
0201 
0202         template <typename ArgT>
0203         struct result {
0204 
0205             typedef bool type;
0206         };
0207 
0208         template <typename ArgT>
0209         bool
0210         operator()(ArgT &val) const
0211         {
0212             return boost::wave::grammars::closures::as_bool(val);
0213         }
0214     };
0215     phoenix::function<operator_as_bool> const as_bool;
0216 
0217 ///////////////////////////////////////////////////////////////////////////////
0218 //
0219 //  Handle closure value operators with proper error propagation
0220 //
0221 ///////////////////////////////////////////////////////////////////////////////
0222 #define BOOST_WAVE_BINARYOP(op, optok)                                        \
0223     struct operator_binary_ ## op {                                           \
0224                                                                               \
0225         template <typename Arg1T, typename Arg2T>                             \
0226         struct result {                                                       \
0227                                                                               \
0228             typedef boost::wave::grammars::closures::closure_value type;      \
0229         };                                                                    \
0230                                                                               \
0231         template <typename Arg1T, typename Arg2T>                             \
0232         boost::wave::grammars::closures::closure_value                        \
0233         operator()(Arg1T &val1, Arg2T &val2) const                            \
0234         {                                                                     \
0235             return val1 optok val2;                                           \
0236         }                                                                     \
0237     };                                                                        \
0238     phoenix::function<operator_binary_ ## op> const binary_ ## op             \
0239     /**/
0240 
0241     BOOST_WAVE_BINARYOP(and, &&);
0242     BOOST_WAVE_BINARYOP(or, ||);
0243 
0244     BOOST_WAVE_BINARYOP(bitand, &);
0245     BOOST_WAVE_BINARYOP(bitor, |);
0246     BOOST_WAVE_BINARYOP(bitxor, ^);
0247 
0248     BOOST_WAVE_BINARYOP(lesseq, <=);
0249     BOOST_WAVE_BINARYOP(less, <);
0250     BOOST_WAVE_BINARYOP(greater, >);
0251     BOOST_WAVE_BINARYOP(greateq, >=);
0252     BOOST_WAVE_BINARYOP(eq, ==);
0253     BOOST_WAVE_BINARYOP(ne, !=);
0254 
0255 #undef BOOST_WAVE_BINARYOP
0256 
0257 ///////////////////////////////////////////////////////////////////////////////
0258 #define BOOST_WAVE_UNARYOP(op, optok)                                         \
0259     struct operator_unary_ ## op {                                            \
0260                                                                               \
0261         template <typename ArgT>                                              \
0262         struct result {                                                       \
0263                                                                               \
0264             typedef boost::wave::grammars::closures::closure_value type;      \
0265         };                                                                    \
0266                                                                               \
0267         template <typename ArgT>                                              \
0268         boost::wave::grammars::closures::closure_value                        \
0269         operator()(ArgT &val) const                                           \
0270         {                                                                     \
0271             return optok val;                                                 \
0272         }                                                                     \
0273     };                                                                        \
0274     phoenix::function<operator_unary_ ## op> const unary_ ## op               \
0275     /**/
0276 
0277     BOOST_WAVE_UNARYOP(neg, !);
0278 
0279 #undef BOOST_WAVE_UNARYOP
0280 
0281 }   // namespace impl
0282 
0283 ///////////////////////////////////////////////////////////////////////////////
0284 //  define, whether the rule's should generate some debug output
0285 #define TRACE_CPP_EXPR_GRAMMAR \
0286     bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_CPP_EXPR_GRAMMAR) \
0287     /**/
0288 
0289 struct expression_grammar :
0290     public boost::spirit::classic::grammar<
0291         expression_grammar,
0292         closures::cpp_expr_closure::context_t
0293     >
0294 {
0295     expression_grammar()
0296     {
0297         BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this, "expression_grammar",
0298             TRACE_CPP_EXPR_GRAMMAR);
0299     }
0300 
0301     // no need for copy constructor/assignment operator
0302     expression_grammar(expression_grammar const&);
0303     expression_grammar& operator= (expression_grammar const&);
0304 
0305     template <typename ScannerT>
0306     struct definition
0307     {
0308         typedef closures::cpp_expr_closure closure_type;
0309         typedef boost::spirit::classic::rule<ScannerT, closure_type::context_t> rule_t;
0310         typedef boost::spirit::classic::rule<ScannerT> simple_rule_t;
0311 
0312         simple_rule_t pp_expression;
0313 
0314         rule_t const_exp;
0315         rule_t logical_or_exp, logical_and_exp;
0316         rule_t inclusive_or_exp, exclusive_or_exp, and_exp;
0317         rule_t cmp_equality, cmp_relational;
0318         rule_t shift_exp;
0319         rule_t add_exp, multiply_exp;
0320         rule_t unary_exp, primary_exp, constant;
0321 
0322         rule_t const_exp_nocalc;
0323         rule_t logical_or_exp_nocalc, logical_and_exp_nocalc;
0324         rule_t inclusive_or_exp_nocalc, exclusive_or_exp_nocalc, and_exp_nocalc;
0325         rule_t cmp_equality_nocalc, cmp_relational_nocalc;
0326         rule_t shift_exp_nocalc;
0327         rule_t add_exp_nocalc, multiply_exp_nocalc;
0328         rule_t unary_exp_nocalc, primary_exp_nocalc, constant_nocalc;
0329 
0330         boost::spirit::classic::subrule<0, closure_type::context_t> const_exp_subrule;
0331 
0332         definition(expression_grammar const &self)
0333         {
0334             using namespace boost::spirit::classic;
0335             using namespace phoenix;
0336             using namespace boost::wave;
0337             using boost::wave::util::pattern_p;
0338 
0339             pp_expression
0340                 =   const_exp[self.val = arg1]
0341                 ;
0342 
0343             const_exp
0344                 =   logical_or_exp[const_exp.val = arg1]
0345                     >> !(const_exp_subrule =
0346                             ch_p(T_QUESTION_MARK)
0347                             >>  const_exp
0348                                 [
0349                                     const_exp_subrule.val = arg1
0350                                 ]
0351                             >>  ch_p(T_COLON)
0352                             >>  const_exp
0353                                 [
0354                                     const_exp_subrule.val =
0355                                         impl::questionmark(const_exp.val,
0356                                             const_exp_subrule.val, arg1)
0357                                 ]
0358                         )[const_exp.val = arg1]
0359                 ;
0360 
0361             logical_or_exp
0362                 =   logical_and_exp[logical_or_exp.val = arg1]
0363                     >> *(   if_p(impl::as_bool(logical_or_exp.val))
0364                             [
0365                                 // if one of the || operators is true, no more
0366                                 // evaluation is required
0367                                 pattern_p(T_OROR, MainTokenMask)
0368                                 >>  logical_and_exp_nocalc
0369                                     [
0370                                         logical_or_exp.val =
0371                                             impl::to_bool(logical_or_exp.val)
0372                                     ]
0373                             ]
0374                             .else_p
0375                             [
0376                                 pattern_p(T_OROR, MainTokenMask)
0377                                 >>  logical_and_exp
0378                                     [
0379                                         logical_or_exp.val =
0380                                             impl::binary_or(logical_or_exp.val, arg1)
0381                                     ]
0382                             ]
0383                         )
0384                 ;
0385 
0386             logical_and_exp
0387                 =   inclusive_or_exp[logical_and_exp.val = arg1]
0388                     >> *(   if_p(impl::as_bool(logical_and_exp.val))
0389                             [
0390                                 pattern_p(T_ANDAND, MainTokenMask)
0391                                 >>  inclusive_or_exp
0392                                     [
0393                                         logical_and_exp.val =
0394                                             impl::binary_and(logical_and_exp.val, arg1)
0395                                     ]
0396                             ]
0397                             .else_p
0398                             [
0399                                 // if one of the && operators is false, no more
0400                                 // evaluation is required
0401                                 pattern_p(T_ANDAND, MainTokenMask)
0402                                 >>  inclusive_or_exp_nocalc
0403                                     [
0404                                         logical_and_exp.val =
0405                                             impl::to_bool(logical_and_exp.val)
0406                                     ]
0407                             ]
0408                         )
0409                 ;
0410 
0411             inclusive_or_exp
0412                 =   exclusive_or_exp[inclusive_or_exp.val = arg1]
0413                     >> *(   pattern_p(T_OR, MainTokenMask)
0414                             >>  exclusive_or_exp
0415                                 [
0416                                     inclusive_or_exp.val =
0417                                         impl::binary_bitor(inclusive_or_exp.val, arg1)
0418                                 ]
0419                         )
0420                 ;
0421 
0422             exclusive_or_exp
0423                 =   and_exp[exclusive_or_exp.val = arg1]
0424                     >> *(   pattern_p(T_XOR, MainTokenMask)
0425                             >>  and_exp
0426                                 [
0427                                     exclusive_or_exp.val =
0428                                         impl::binary_bitxor(exclusive_or_exp.val, arg1)
0429                                 ]
0430                         )
0431                 ;
0432 
0433             and_exp
0434                 =   cmp_equality[and_exp.val = arg1]
0435                     >> *(   pattern_p(T_AND, MainTokenMask)
0436                             >>  cmp_equality
0437                                 [
0438                                     and_exp.val =
0439                                         impl::binary_bitand(and_exp.val, arg1)
0440                                 ]
0441                         )
0442                 ;
0443 
0444             cmp_equality
0445                 =   cmp_relational[cmp_equality.val = arg1]
0446                     >> *(   ch_p(T_EQUAL)
0447                             >>  cmp_relational
0448                                 [
0449                                     cmp_equality.val =
0450                                         impl::binary_eq(cmp_equality.val, arg1)
0451                                 ]
0452                         |   pattern_p(T_NOTEQUAL, MainTokenMask)
0453                             >>  cmp_relational
0454                                 [
0455                                     cmp_equality.val =
0456                                         impl::binary_ne(cmp_equality.val, arg1)
0457                                 ]
0458                         )
0459                 ;
0460 
0461             cmp_relational
0462                 =   shift_exp[cmp_relational.val = arg1]
0463                     >> *(   ch_p(T_LESSEQUAL)
0464                             >>  shift_exp
0465                                 [
0466                                     cmp_relational.val =
0467                                         impl::binary_lesseq(cmp_relational.val, arg1)
0468                                 ]
0469                         |   ch_p(T_GREATEREQUAL)
0470                             >>  shift_exp
0471                                 [
0472                                     cmp_relational.val =
0473                                         impl::binary_greateq(cmp_relational.val, arg1)
0474                                 ]
0475                         |   ch_p(T_LESS)
0476                             >>  shift_exp
0477                                 [
0478                                     cmp_relational.val =
0479                                         impl::binary_less(cmp_relational.val, arg1)
0480                                 ]
0481                         |   ch_p(T_GREATER)
0482                             >>  shift_exp
0483                                 [
0484                                     cmp_relational.val =
0485                                         impl::binary_greater(cmp_relational.val, arg1)
0486                                 ]
0487                         )
0488                 ;
0489 
0490             shift_exp
0491                 =   add_exp[shift_exp.val = arg1]
0492                     >> *(   ch_p(T_SHIFTLEFT)
0493                             >>  add_exp
0494                                 [
0495                                     shift_exp.val <<= arg1
0496                                 ]
0497                         |   ch_p(T_SHIFTRIGHT)
0498                             >>  add_exp
0499                                 [
0500                                     shift_exp.val >>= arg1
0501                                 ]
0502                         )
0503                 ;
0504 
0505             add_exp
0506                 =   multiply_exp[add_exp.val = arg1]
0507                     >> *(   ch_p(T_PLUS)
0508                             >>  multiply_exp
0509                                 [
0510                                     add_exp.val += arg1
0511                                 ]
0512                         |   ch_p(T_MINUS)
0513                             >>  multiply_exp
0514                                 [
0515                                     add_exp.val -= arg1
0516                                 ]
0517                         )
0518                 ;
0519 
0520             multiply_exp
0521                 =   unary_exp[multiply_exp.val = arg1]
0522                     >> *(   ch_p(T_STAR)
0523                             >>  unary_exp
0524                                 [
0525                                     multiply_exp.val *= arg1
0526                                 ]
0527                         |   ch_p(T_DIVIDE)
0528                             >>  unary_exp
0529                                 [
0530                                     multiply_exp.val /= arg1
0531                                 ]
0532                         |   ch_p(T_PERCENT)
0533                             >>  unary_exp
0534                                 [
0535                                     multiply_exp.val %= arg1
0536                                 ]
0537                         )
0538                 ;
0539 
0540             unary_exp
0541                 =   primary_exp[unary_exp.val = arg1]
0542                 |   ch_p(T_PLUS) >> unary_exp
0543                     [
0544                         unary_exp.val = arg1
0545                     ]
0546                 |   ch_p(T_MINUS) >> unary_exp
0547                     [
0548                         unary_exp.val = -arg1
0549                     ]
0550                 |   pattern_p(T_COMPL, MainTokenMask) >> unary_exp
0551                     [
0552                         unary_exp.val = ~arg1
0553                     ]
0554                 |   pattern_p(T_NOT, MainTokenMask) >> unary_exp
0555                     [
0556                         unary_exp.val = impl::unary_neg(arg1)
0557                     ]
0558                 ;
0559 
0560             primary_exp
0561                 =   constant[primary_exp.val = arg1]
0562                 |   ch_p(T_LEFTPAREN)
0563                     >> const_exp[primary_exp.val = arg1]
0564                     >> ch_p(T_RIGHTPAREN)
0565                 ;
0566 
0567             constant
0568                 =   ch_p(T_PP_NUMBER)
0569                     [
0570                         constant.val = impl::as_intlit(arg1)
0571                     ]
0572                 |   ch_p(T_INTLIT)
0573                     [
0574                         constant.val = impl::as_intlit(arg1)
0575                     ]
0576                 |   ch_p(T_LONGINTLIT)
0577                     [
0578                         constant.val = impl::as_intlit(arg1)
0579                     ]
0580                 |   ch_p(T_CHARLIT)
0581                     [
0582                         constant.val = impl::as_chlit(arg1)
0583                     ]
0584                 ;
0585 
0586             //  here follows the same grammar, but without any embedded
0587             //  calculations
0588             const_exp_nocalc
0589                 =   logical_or_exp_nocalc
0590                     >> !(   ch_p(T_QUESTION_MARK)
0591                             >>  const_exp_nocalc
0592                             >>  ch_p(T_COLON)
0593                             >>  const_exp_nocalc
0594                         )
0595                 ;
0596 
0597             logical_or_exp_nocalc
0598                 =   logical_and_exp_nocalc
0599                     >> *(   pattern_p(T_OROR, MainTokenMask)
0600                             >>  logical_and_exp_nocalc
0601                         )
0602                 ;
0603 
0604             logical_and_exp_nocalc
0605                 =   inclusive_or_exp_nocalc
0606                     >> *(   pattern_p(T_ANDAND, MainTokenMask)
0607                             >>  inclusive_or_exp_nocalc
0608                         )
0609                 ;
0610 
0611             inclusive_or_exp_nocalc
0612                 =   exclusive_or_exp_nocalc
0613                     >> *(   pattern_p(T_OR, MainTokenMask)
0614                             >>  exclusive_or_exp_nocalc
0615                         )
0616                 ;
0617 
0618             exclusive_or_exp_nocalc
0619                 =   and_exp_nocalc
0620                     >> *(   pattern_p(T_XOR, MainTokenMask)
0621                             >>  and_exp_nocalc
0622                         )
0623                 ;
0624 
0625             and_exp_nocalc
0626                 =   cmp_equality_nocalc
0627                     >> *(   pattern_p(T_AND, MainTokenMask)
0628                             >>  cmp_equality_nocalc
0629                         )
0630                 ;
0631 
0632             cmp_equality_nocalc
0633                 =   cmp_relational_nocalc
0634                     >> *(   ch_p(T_EQUAL)
0635                             >>  cmp_relational_nocalc
0636                         |   pattern_p(T_NOTEQUAL, MainTokenMask)
0637                             >>  cmp_relational_nocalc
0638                         )
0639                 ;
0640 
0641             cmp_relational_nocalc
0642                 =   shift_exp_nocalc
0643                     >> *(   ch_p(T_LESSEQUAL)
0644                             >>  shift_exp_nocalc
0645                         |   ch_p(T_GREATEREQUAL)
0646                             >>  shift_exp_nocalc
0647                         |   ch_p(T_LESS)
0648                             >>  shift_exp_nocalc
0649                         |   ch_p(T_GREATER)
0650                             >>  shift_exp_nocalc
0651                         )
0652                 ;
0653 
0654             shift_exp_nocalc
0655                 =   add_exp_nocalc
0656                     >> *(   ch_p(T_SHIFTLEFT)
0657                             >>  add_exp_nocalc
0658                         |   ch_p(T_SHIFTRIGHT)
0659                             >>  add_exp_nocalc
0660                         )
0661                 ;
0662 
0663             add_exp_nocalc
0664                 =   multiply_exp_nocalc
0665                     >> *(   ch_p(T_PLUS)
0666                             >>  multiply_exp_nocalc
0667                         |   ch_p(T_MINUS)
0668                             >>  multiply_exp_nocalc
0669                         )
0670                 ;
0671 
0672             multiply_exp_nocalc
0673                 =   unary_exp_nocalc
0674                     >> *(   ch_p(T_STAR)
0675                             >>  unary_exp_nocalc
0676                         |   ch_p(T_DIVIDE)
0677                             >>  unary_exp_nocalc
0678                         |   ch_p(T_PERCENT)
0679                             >>  unary_exp_nocalc
0680                         )
0681                 ;
0682 
0683             unary_exp_nocalc
0684                 =   primary_exp_nocalc
0685                 |   ch_p(T_PLUS) >> unary_exp_nocalc
0686                 |   ch_p(T_MINUS) >> unary_exp_nocalc
0687                 |   pattern_p(T_COMPL, MainTokenMask) >> unary_exp_nocalc
0688                 |   pattern_p(T_NOT, MainTokenMask) >> unary_exp_nocalc
0689                 ;
0690 
0691             primary_exp_nocalc
0692                 =   constant_nocalc
0693                 |   ch_p(T_LEFTPAREN)
0694                     >> const_exp_nocalc
0695                     >> ch_p(T_RIGHTPAREN)
0696                 ;
0697 
0698             constant_nocalc
0699                 =   ch_p(T_PP_NUMBER)
0700                 |   ch_p(T_INTLIT)
0701                 |   ch_p(T_LONGINTLIT)
0702                 |   ch_p(T_CHARLIT)
0703                 ;
0704 
0705             BOOST_SPIRIT_DEBUG_TRACE_RULE(pp_expression, TRACE_CPP_EXPR_GRAMMAR);
0706             BOOST_SPIRIT_DEBUG_TRACE_RULE(const_exp, TRACE_CPP_EXPR_GRAMMAR);
0707             BOOST_SPIRIT_DEBUG_TRACE_RULE(logical_or_exp, TRACE_CPP_EXPR_GRAMMAR);
0708             BOOST_SPIRIT_DEBUG_TRACE_RULE(logical_and_exp, TRACE_CPP_EXPR_GRAMMAR);
0709             BOOST_SPIRIT_DEBUG_TRACE_RULE(inclusive_or_exp, TRACE_CPP_EXPR_GRAMMAR);
0710             BOOST_SPIRIT_DEBUG_TRACE_RULE(exclusive_or_exp, TRACE_CPP_EXPR_GRAMMAR);
0711             BOOST_SPIRIT_DEBUG_TRACE_RULE(and_exp, TRACE_CPP_EXPR_GRAMMAR);
0712             BOOST_SPIRIT_DEBUG_TRACE_RULE(cmp_equality, TRACE_CPP_EXPR_GRAMMAR);
0713             BOOST_SPIRIT_DEBUG_TRACE_RULE(cmp_relational, TRACE_CPP_EXPR_GRAMMAR);
0714             BOOST_SPIRIT_DEBUG_TRACE_RULE(shift_exp, TRACE_CPP_EXPR_GRAMMAR);
0715             BOOST_SPIRIT_DEBUG_TRACE_RULE(add_exp, TRACE_CPP_EXPR_GRAMMAR);
0716             BOOST_SPIRIT_DEBUG_TRACE_RULE(multiply_exp, TRACE_CPP_EXPR_GRAMMAR);
0717             BOOST_SPIRIT_DEBUG_TRACE_RULE(unary_exp, TRACE_CPP_EXPR_GRAMMAR);
0718             BOOST_SPIRIT_DEBUG_TRACE_RULE(primary_exp, TRACE_CPP_EXPR_GRAMMAR);
0719             BOOST_SPIRIT_DEBUG_TRACE_RULE(constant, TRACE_CPP_EXPR_GRAMMAR);
0720             BOOST_SPIRIT_DEBUG_TRACE_RULE(const_exp_subrule, TRACE_CPP_EXPR_GRAMMAR);
0721 
0722             BOOST_SPIRIT_DEBUG_TRACE_RULE(const_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
0723             BOOST_SPIRIT_DEBUG_TRACE_RULE(logical_or_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
0724             BOOST_SPIRIT_DEBUG_TRACE_RULE(logical_and_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
0725             BOOST_SPIRIT_DEBUG_TRACE_RULE(inclusive_or_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
0726             BOOST_SPIRIT_DEBUG_TRACE_RULE(exclusive_or_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
0727             BOOST_SPIRIT_DEBUG_TRACE_RULE(and_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
0728             BOOST_SPIRIT_DEBUG_TRACE_RULE(cmp_equality_nocalc, TRACE_CPP_EXPR_GRAMMAR);
0729             BOOST_SPIRIT_DEBUG_TRACE_RULE(cmp_relational_nocalc, TRACE_CPP_EXPR_GRAMMAR);
0730             BOOST_SPIRIT_DEBUG_TRACE_RULE(shift_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
0731             BOOST_SPIRIT_DEBUG_TRACE_RULE(add_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
0732             BOOST_SPIRIT_DEBUG_TRACE_RULE(multiply_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
0733             BOOST_SPIRIT_DEBUG_TRACE_RULE(unary_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
0734             BOOST_SPIRIT_DEBUG_TRACE_RULE(primary_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
0735             BOOST_SPIRIT_DEBUG_TRACE_RULE(constant_nocalc, TRACE_CPP_EXPR_GRAMMAR);
0736         }
0737 
0738         // start rule of this grammar
0739         simple_rule_t const& start() const
0740         { return pp_expression; }
0741     };
0742 };
0743 
0744 ///////////////////////////////////////////////////////////////////////////////
0745 #undef TRACE_CPP_EXPR_GRAMMAR
0746 
0747 ///////////////////////////////////////////////////////////////////////////////
0748 //
0749 //  The following function is defined here, to allow the separation of
0750 //  the compilation of the expression_grammar from the function using it.
0751 //
0752 ///////////////////////////////////////////////////////////////////////////////
0753 
0754 #if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
0755 #define BOOST_WAVE_EXPRGRAMMAR_GEN_INLINE
0756 #else
0757 #define BOOST_WAVE_EXPRGRAMMAR_GEN_INLINE inline
0758 #endif
0759 
0760 template <typename TokenT>
0761 BOOST_WAVE_EXPRGRAMMAR_GEN_INLINE
0762 bool
0763 expression_grammar_gen<TokenT>::evaluate(
0764     typename token_sequence_type::const_iterator const &first,
0765     typename token_sequence_type::const_iterator const &last,
0766     typename token_type::position_type const &act_pos,
0767     bool if_block_status, value_error &status)
0768 {
0769     using namespace boost::spirit::classic;
0770     using namespace boost::wave;
0771     using namespace boost::wave::grammars::closures;
0772 
0773     using boost::wave::util::impl::as_string;
0774 
0775     typedef typename token_sequence_type::const_iterator iterator_type;
0776     typedef typename token_sequence_type::value_type::string_type string_type;
0777 
0778     parse_info<iterator_type> hit(first);
0779     closure_value result;             // expression result
0780 
0781 #if !defined(BOOST_NO_EXCEPTIONS)
0782     try
0783 #endif
0784     {
0785         expression_grammar g;             // expression grammar
0786         hit = parse (first, last, g[spirit_assign_actor(result)],
0787                      ch_p(T_SPACE) | ch_p(T_CCOMMENT) | ch_p(T_CPPCOMMENT));
0788 
0789         if (!hit.hit) {
0790             // expression is illformed
0791             if (if_block_status) {
0792                 string_type expression = as_string<string_type>(first, last);
0793                 if (0 == expression.size())
0794                     expression = "<empty expression>";
0795                 BOOST_WAVE_THROW(preprocess_exception, ill_formed_expression,
0796                     expression.c_str(), act_pos);
0797                 return false;
0798             }
0799             else {
0800                 //  as the if_block_status is false no errors will be reported
0801                 return false;
0802             }
0803         }
0804     }
0805 #if !defined(BOOST_NO_EXCEPTIONS)
0806     catch (boost::wave::preprocess_exception const& e) {
0807         // expression is illformed
0808         if (if_block_status) {
0809             boost::throw_exception(e);
0810             return false;
0811         }
0812         else         {
0813             //  as the if_block_status is false no errors will be reported
0814             return false;
0815         }
0816     }
0817 #endif
0818 
0819     if (!hit.full) {
0820         // The token list starts with a valid expression, but there remains
0821         // something. If the remainder consists out of whitespace only, the
0822         // expression is still valid.
0823         iterator_type next = hit.stop;
0824 
0825         while (next != last) {
0826             switch (token_id(*next)) {
0827             case T_SPACE:
0828             case T_SPACE2:
0829             case T_CCOMMENT:
0830                 break;                      // ok continue
0831 
0832             case T_NEWLINE:
0833             case T_EOF:
0834             case T_CPPCOMMENT:              // contains newline
0835                 return as_bool(result);     // expression is valid
0836 
0837             default:
0838                 // expression is illformed
0839                 if (if_block_status) {
0840                     string_type expression = as_string<string_type>(first, last);
0841                     if (0 == expression.size())
0842                         expression = "<empty expression>";
0843                     BOOST_WAVE_THROW(preprocess_exception, ill_formed_expression,
0844                         expression.c_str(), act_pos);
0845                     return false;
0846                 }
0847                 else {
0848                     //  as the if_block_status is false no errors will be reported
0849                     return false;
0850                 }
0851             }
0852             ++next;
0853         }
0854     }
0855 
0856     if (error_noerror != result.is_valid()) // division or other error by zero occurred
0857         status = result.is_valid();
0858 
0859     // token sequence is a valid expression
0860     return as_bool(result);
0861 }
0862 
0863 #undef BOOST_WAVE_EXPRGRAMMAR_GEN_INLINE
0864 
0865 ///////////////////////////////////////////////////////////////////////////////
0866 }   // namespace grammars
0867 }   // namespace wave
0868 }   // namespace boost
0869 
0870 // the suffix header occurs after all of the code
0871 #ifdef BOOST_HAS_ABI_HEADERS
0872 #include BOOST_ABI_SUFFIX
0873 #endif
0874 
0875 #endif // !defined(BOOST_CPP_EXPRESSION_GRAMMAR_HPP_099CD1A4_A6C0_44BE_8F24_0B00F5BE5674_INCLUDED)