123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875 |
- /*=============================================================================
- Boost.Wave: A Standard compliant C++ preprocessor library
- http://www.boost.org/
- Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost
- Software License, Version 1.0. (See accompanying file
- LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- =============================================================================*/
- #if !defined(BOOST_CPP_EXPRESSION_GRAMMAR_HPP_099CD1A4_A6C0_44BE_8F24_0B00F5BE5674_INCLUDED)
- #define BOOST_CPP_EXPRESSION_GRAMMAR_HPP_099CD1A4_A6C0_44BE_8F24_0B00F5BE5674_INCLUDED
- #include <boost/wave/wave_config.hpp>
- #include <boost/assert.hpp>
- #include <boost/spirit/include/classic_core.hpp>
- #include <boost/spirit/include/classic_closure.hpp>
- #include <boost/spirit/include/classic_if.hpp>
- #include <boost/spirit/include/classic_assign_actor.hpp>
- #include <boost/spirit/include/classic_push_back_actor.hpp>
- #include <boost/spirit/include/phoenix1_functions.hpp>
- #include <boost/spirit/include/phoenix1_operators.hpp>
- #include <boost/spirit/include/phoenix1_primitives.hpp>
- #include <boost/spirit/include/phoenix1_statements.hpp>
- #include <boost/spirit/include/phoenix1_casts.hpp>
- #include <boost/wave/token_ids.hpp>
- #include <boost/wave/cpp_exceptions.hpp>
- #include <boost/wave/grammars/cpp_expression_grammar_gen.hpp>
- #include <boost/wave/grammars/cpp_literal_grammar_gen.hpp>
- #include <boost/wave/grammars/cpp_expression_value.hpp>
- #include <boost/wave/util/pattern_parser.hpp>
- #include <boost/wave/util/macro_helpers.hpp>
- #if !defined(spirit_append_actor)
- #define spirit_append_actor(actor) boost::spirit::classic::push_back_a(actor)
- #define spirit_assign_actor(actor) boost::spirit::classic::assign_a(actor)
- #endif // !defined(spirit_append_actor)
- // this must occur after all of the includes and before any code appears
- #ifdef BOOST_HAS_ABI_HEADERS
- #include BOOST_ABI_PREFIX
- #endif
- ///////////////////////////////////////////////////////////////////////////////
- //
- // Encapsulation of the grammar for evaluation of constant preprocessor
- // expressions
- //
- ///////////////////////////////////////////////////////////////////////////////
- namespace boost {
- namespace wave {
- namespace grammars {
- namespace closures {
- ///////////////////////////////////////////////////////////////////////////////
- //
- // define the closure type used throughout the C++ expression grammar
- //
- // Throughout this grammar all literal tokens are stored into a
- // closure_value variables, which converts the types appropriately, where
- // required.
- //
- ///////////////////////////////////////////////////////////////////////////////
- struct cpp_expr_closure
- : boost::spirit::classic::closure<cpp_expr_closure, closure_value>
- {
- member1 val;
- };
- } // namespace closures
- namespace impl {
- ///////////////////////////////////////////////////////////////////////////////
- //
- // convert the given token value (integer literal) to a unsigned long
- //
- ///////////////////////////////////////////////////////////////////////////////
- struct convert_intlit {
- template <typename ArgT>
- struct result {
- typedef boost::wave::grammars::closures::closure_value type;
- };
- template <typename TokenT>
- boost::wave::grammars::closures::closure_value
- operator()(TokenT const &token) const
- {
- typedef boost::wave::grammars::closures::closure_value return_type;
- bool is_unsigned = false;
- uint_literal_type ul = intlit_grammar_gen<TokenT>::evaluate(token,
- is_unsigned);
- return is_unsigned ?
- return_type(ul) : return_type(static_cast<int_literal_type>(ul));
- }
- };
- phoenix::function<convert_intlit> const as_intlit;
- ///////////////////////////////////////////////////////////////////////////////
- //
- // Convert the given token value (character literal) to a unsigned int
- //
- ///////////////////////////////////////////////////////////////////////////////
- struct convert_chlit {
- template <typename ArgT>
- struct result {
- typedef boost::wave::grammars::closures::closure_value type;
- };
- template <typename TokenT>
- boost::wave::grammars::closures::closure_value
- operator()(TokenT const &token) const
- {
- typedef boost::wave::grammars::closures::closure_value return_type;
- value_error status = error_noerror;
- // If the literal is a wchar_t and wchar_t is represented by a
- // signed integral type, then the created value will be signed as
- // well, otherwise we assume unsigned values.
- #if BOOST_WAVE_WCHAR_T_SIGNEDNESS == BOOST_WAVE_WCHAR_T_AUTOSELECT
- if ('L' == token.get_value()[0] && std::numeric_limits<wchar_t>::is_signed)
- {
- int value = chlit_grammar_gen<int, TokenT>::evaluate(token, status);
- return return_type(value, status);
- }
- #elif BOOST_WAVE_WCHAR_T_SIGNEDNESS == BOOST_WAVE_WCHAR_T_FORCE_SIGNED
- if ('L' == token.get_value()[0])
- {
- int value = chlit_grammar_gen<int, TokenT>::evaluate(token, status);
- return return_type(value, status);
- }
- #endif
- unsigned int value = chlit_grammar_gen<unsigned int, TokenT>::evaluate(token, status);
- return return_type(value, status);
- }
- };
- phoenix::function<convert_chlit> const as_chlit;
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Handle the ?: operator with correct type and error propagation
- //
- ////////////////////////////////////////////////////////////////////////////////
- struct operator_questionmark {
- template <typename CondT, typename Arg1T, typename Arg2T>
- struct result {
- typedef boost::wave::grammars::closures::closure_value type;
- };
- template <typename CondT, typename Arg1T, typename Arg2T>
- boost::wave::grammars::closures::closure_value
- operator()(CondT const &cond, Arg1T &val1, Arg2T const &val2) const
- {
- return val1.handle_questionmark(cond, val2);
- }
- };
- phoenix::function<operator_questionmark> const questionmark;
- ///////////////////////////////////////////////////////////////////////////////
- //
- // Handle type conversion conserving error conditions
- //
- ///////////////////////////////////////////////////////////////////////////////
- struct operator_to_bool {
- template <typename ArgT>
- struct result {
- typedef boost::wave::grammars::closures::closure_value type;
- };
- template <typename ArgT>
- boost::wave::grammars::closures::closure_value
- operator()(ArgT &val) const
- {
- typedef boost::wave::grammars::closures::closure_value return_type;
- return return_type(
- boost::wave::grammars::closures::as_bool(val), val.is_valid());
- }
- };
- phoenix::function<operator_to_bool> const to_bool;
- ///////////////////////////////////////////////////////////////////////////////
- //
- // Handle explicit type conversion
- //
- ///////////////////////////////////////////////////////////////////////////////
- struct operator_as_bool {
- template <typename ArgT>
- struct result {
- typedef bool type;
- };
- template <typename ArgT>
- bool
- operator()(ArgT &val) const
- {
- return boost::wave::grammars::closures::as_bool(val);
- }
- };
- phoenix::function<operator_as_bool> const as_bool;
- ///////////////////////////////////////////////////////////////////////////////
- //
- // Handle closure value operators with proper error propagation
- //
- ///////////////////////////////////////////////////////////////////////////////
- #define BOOST_WAVE_BINARYOP(op, optok) \
- struct operator_binary_ ## op { \
- \
- template <typename Arg1T, typename Arg2T> \
- struct result { \
- \
- typedef boost::wave::grammars::closures::closure_value type; \
- }; \
- \
- template <typename Arg1T, typename Arg2T> \
- boost::wave::grammars::closures::closure_value \
- operator()(Arg1T &val1, Arg2T &val2) const \
- { \
- return val1 optok val2; \
- } \
- }; \
- phoenix::function<operator_binary_ ## op> const binary_ ## op \
- /**/
- BOOST_WAVE_BINARYOP(and, &&);
- BOOST_WAVE_BINARYOP(or, ||);
- BOOST_WAVE_BINARYOP(bitand, &);
- BOOST_WAVE_BINARYOP(bitor, |);
- BOOST_WAVE_BINARYOP(bitxor, ^);
- BOOST_WAVE_BINARYOP(lesseq, <=);
- BOOST_WAVE_BINARYOP(less, <);
- BOOST_WAVE_BINARYOP(greater, >);
- BOOST_WAVE_BINARYOP(greateq, >=);
- BOOST_WAVE_BINARYOP(eq, ==);
- BOOST_WAVE_BINARYOP(ne, !=);
- #undef BOOST_WAVE_BINARYOP
- ///////////////////////////////////////////////////////////////////////////////
- #define BOOST_WAVE_UNARYOP(op, optok) \
- struct operator_unary_ ## op { \
- \
- template <typename ArgT> \
- struct result { \
- \
- typedef boost::wave::grammars::closures::closure_value type; \
- }; \
- \
- template <typename ArgT> \
- boost::wave::grammars::closures::closure_value \
- operator()(ArgT &val) const \
- { \
- return optok val; \
- } \
- }; \
- phoenix::function<operator_unary_ ## op> const unary_ ## op \
- /**/
- BOOST_WAVE_UNARYOP(neg, !);
- #undef BOOST_WAVE_UNARYOP
- } // namespace impl
- ///////////////////////////////////////////////////////////////////////////////
- // define, whether the rule's should generate some debug output
- #define TRACE_CPP_EXPR_GRAMMAR \
- bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_CPP_EXPR_GRAMMAR) \
- /**/
- struct expression_grammar :
- public boost::spirit::classic::grammar<
- expression_grammar,
- closures::cpp_expr_closure::context_t
- >
- {
- expression_grammar()
- {
- BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this, "expression_grammar",
- TRACE_CPP_EXPR_GRAMMAR);
- }
- // no need for copy constructor/assignment operator
- expression_grammar(expression_grammar const&);
- expression_grammar& operator= (expression_grammar const&);
- template <typename ScannerT>
- struct definition
- {
- typedef closures::cpp_expr_closure closure_type;
- typedef boost::spirit::classic::rule<ScannerT, closure_type::context_t> rule_t;
- typedef boost::spirit::classic::rule<ScannerT> simple_rule_t;
- simple_rule_t pp_expression;
- rule_t const_exp;
- rule_t logical_or_exp, logical_and_exp;
- rule_t inclusive_or_exp, exclusive_or_exp, and_exp;
- rule_t cmp_equality, cmp_relational;
- rule_t shift_exp;
- rule_t add_exp, multiply_exp;
- rule_t unary_exp, primary_exp, constant;
- rule_t const_exp_nocalc;
- rule_t logical_or_exp_nocalc, logical_and_exp_nocalc;
- rule_t inclusive_or_exp_nocalc, exclusive_or_exp_nocalc, and_exp_nocalc;
- rule_t cmp_equality_nocalc, cmp_relational_nocalc;
- rule_t shift_exp_nocalc;
- rule_t add_exp_nocalc, multiply_exp_nocalc;
- rule_t unary_exp_nocalc, primary_exp_nocalc, constant_nocalc;
- boost::spirit::classic::subrule<0, closure_type::context_t> const_exp_subrule;
- definition(expression_grammar const &self)
- {
- using namespace boost::spirit::classic;
- using namespace phoenix;
- using namespace boost::wave;
- using boost::wave::util::pattern_p;
- pp_expression
- = const_exp[self.val = arg1]
- ;
- const_exp
- = logical_or_exp[const_exp.val = arg1]
- >> !(const_exp_subrule =
- ch_p(T_QUESTION_MARK)
- >> const_exp
- [
- const_exp_subrule.val = arg1
- ]
- >> ch_p(T_COLON)
- >> const_exp
- [
- const_exp_subrule.val =
- impl::questionmark(const_exp.val,
- const_exp_subrule.val, arg1)
- ]
- )[const_exp.val = arg1]
- ;
- logical_or_exp
- = logical_and_exp[logical_or_exp.val = arg1]
- >> *( if_p(impl::as_bool(logical_or_exp.val))
- [
- // if one of the || operators is true, no more
- // evaluation is required
- pattern_p(T_OROR, MainTokenMask)
- >> logical_and_exp_nocalc
- [
- logical_or_exp.val =
- impl::to_bool(logical_or_exp.val)
- ]
- ]
- .else_p
- [
- pattern_p(T_OROR, MainTokenMask)
- >> logical_and_exp
- [
- logical_or_exp.val =
- impl::binary_or(logical_or_exp.val, arg1)
- ]
- ]
- )
- ;
- logical_and_exp
- = inclusive_or_exp[logical_and_exp.val = arg1]
- >> *( if_p(impl::as_bool(logical_and_exp.val))
- [
- pattern_p(T_ANDAND, MainTokenMask)
- >> inclusive_or_exp
- [
- logical_and_exp.val =
- impl::binary_and(logical_and_exp.val, arg1)
- ]
- ]
- .else_p
- [
- // if one of the && operators is false, no more
- // evaluation is required
- pattern_p(T_ANDAND, MainTokenMask)
- >> inclusive_or_exp_nocalc
- [
- logical_and_exp.val =
- impl::to_bool(logical_and_exp.val)
- ]
- ]
- )
- ;
- inclusive_or_exp
- = exclusive_or_exp[inclusive_or_exp.val = arg1]
- >> *( pattern_p(T_OR, MainTokenMask)
- >> exclusive_or_exp
- [
- inclusive_or_exp.val =
- impl::binary_bitor(inclusive_or_exp.val, arg1)
- ]
- )
- ;
- exclusive_or_exp
- = and_exp[exclusive_or_exp.val = arg1]
- >> *( pattern_p(T_XOR, MainTokenMask)
- >> and_exp
- [
- exclusive_or_exp.val =
- impl::binary_bitxor(exclusive_or_exp.val, arg1)
- ]
- )
- ;
- and_exp
- = cmp_equality[and_exp.val = arg1]
- >> *( pattern_p(T_AND, MainTokenMask)
- >> cmp_equality
- [
- and_exp.val =
- impl::binary_bitand(and_exp.val, arg1)
- ]
- )
- ;
- cmp_equality
- = cmp_relational[cmp_equality.val = arg1]
- >> *( ch_p(T_EQUAL)
- >> cmp_relational
- [
- cmp_equality.val =
- impl::binary_eq(cmp_equality.val, arg1)
- ]
- | pattern_p(T_NOTEQUAL, MainTokenMask)
- >> cmp_relational
- [
- cmp_equality.val =
- impl::binary_ne(cmp_equality.val, arg1)
- ]
- )
- ;
- cmp_relational
- = shift_exp[cmp_relational.val = arg1]
- >> *( ch_p(T_LESSEQUAL)
- >> shift_exp
- [
- cmp_relational.val =
- impl::binary_lesseq(cmp_relational.val, arg1)
- ]
- | ch_p(T_GREATEREQUAL)
- >> shift_exp
- [
- cmp_relational.val =
- impl::binary_greateq(cmp_relational.val, arg1)
- ]
- | ch_p(T_LESS)
- >> shift_exp
- [
- cmp_relational.val =
- impl::binary_less(cmp_relational.val, arg1)
- ]
- | ch_p(T_GREATER)
- >> shift_exp
- [
- cmp_relational.val =
- impl::binary_greater(cmp_relational.val, arg1)
- ]
- )
- ;
- shift_exp
- = add_exp[shift_exp.val = arg1]
- >> *( ch_p(T_SHIFTLEFT)
- >> add_exp
- [
- shift_exp.val <<= arg1
- ]
- | ch_p(T_SHIFTRIGHT)
- >> add_exp
- [
- shift_exp.val >>= arg1
- ]
- )
- ;
- add_exp
- = multiply_exp[add_exp.val = arg1]
- >> *( ch_p(T_PLUS)
- >> multiply_exp
- [
- add_exp.val += arg1
- ]
- | ch_p(T_MINUS)
- >> multiply_exp
- [
- add_exp.val -= arg1
- ]
- )
- ;
- multiply_exp
- = unary_exp[multiply_exp.val = arg1]
- >> *( ch_p(T_STAR)
- >> unary_exp
- [
- multiply_exp.val *= arg1
- ]
- | ch_p(T_DIVIDE)
- >> unary_exp
- [
- multiply_exp.val /= arg1
- ]
- | ch_p(T_PERCENT)
- >> unary_exp
- [
- multiply_exp.val %= arg1
- ]
- )
- ;
- unary_exp
- = primary_exp[unary_exp.val = arg1]
- | ch_p(T_PLUS) >> unary_exp
- [
- unary_exp.val = arg1
- ]
- | ch_p(T_MINUS) >> unary_exp
- [
- unary_exp.val = -arg1
- ]
- | pattern_p(T_COMPL, MainTokenMask) >> unary_exp
- [
- unary_exp.val = ~arg1
- ]
- | pattern_p(T_NOT, MainTokenMask) >> unary_exp
- [
- unary_exp.val = impl::unary_neg(arg1)
- ]
- ;
- primary_exp
- = constant[primary_exp.val = arg1]
- | ch_p(T_LEFTPAREN)
- >> const_exp[primary_exp.val = arg1]
- >> ch_p(T_RIGHTPAREN)
- ;
- constant
- = ch_p(T_PP_NUMBER)
- [
- constant.val = impl::as_intlit(arg1)
- ]
- | ch_p(T_INTLIT)
- [
- constant.val = impl::as_intlit(arg1)
- ]
- | ch_p(T_LONGINTLIT)
- [
- constant.val = impl::as_intlit(arg1)
- ]
- | ch_p(T_CHARLIT)
- [
- constant.val = impl::as_chlit(arg1)
- ]
- ;
- // here follows the same grammar, but without any embedded
- // calculations
- const_exp_nocalc
- = logical_or_exp_nocalc
- >> !( ch_p(T_QUESTION_MARK)
- >> const_exp_nocalc
- >> ch_p(T_COLON)
- >> const_exp_nocalc
- )
- ;
- logical_or_exp_nocalc
- = logical_and_exp_nocalc
- >> *( pattern_p(T_OROR, MainTokenMask)
- >> logical_and_exp_nocalc
- )
- ;
- logical_and_exp_nocalc
- = inclusive_or_exp_nocalc
- >> *( pattern_p(T_ANDAND, MainTokenMask)
- >> inclusive_or_exp_nocalc
- )
- ;
- inclusive_or_exp_nocalc
- = exclusive_or_exp_nocalc
- >> *( pattern_p(T_OR, MainTokenMask)
- >> exclusive_or_exp_nocalc
- )
- ;
- exclusive_or_exp_nocalc
- = and_exp_nocalc
- >> *( pattern_p(T_XOR, MainTokenMask)
- >> and_exp_nocalc
- )
- ;
- and_exp_nocalc
- = cmp_equality_nocalc
- >> *( pattern_p(T_AND, MainTokenMask)
- >> cmp_equality_nocalc
- )
- ;
- cmp_equality_nocalc
- = cmp_relational_nocalc
- >> *( ch_p(T_EQUAL)
- >> cmp_relational_nocalc
- | pattern_p(T_NOTEQUAL, MainTokenMask)
- >> cmp_relational_nocalc
- )
- ;
- cmp_relational_nocalc
- = shift_exp_nocalc
- >> *( ch_p(T_LESSEQUAL)
- >> shift_exp_nocalc
- | ch_p(T_GREATEREQUAL)
- >> shift_exp_nocalc
- | ch_p(T_LESS)
- >> shift_exp_nocalc
- | ch_p(T_GREATER)
- >> shift_exp_nocalc
- )
- ;
- shift_exp_nocalc
- = add_exp_nocalc
- >> *( ch_p(T_SHIFTLEFT)
- >> add_exp_nocalc
- | ch_p(T_SHIFTRIGHT)
- >> add_exp_nocalc
- )
- ;
- add_exp_nocalc
- = multiply_exp_nocalc
- >> *( ch_p(T_PLUS)
- >> multiply_exp_nocalc
- | ch_p(T_MINUS)
- >> multiply_exp_nocalc
- )
- ;
- multiply_exp_nocalc
- = unary_exp_nocalc
- >> *( ch_p(T_STAR)
- >> unary_exp_nocalc
- | ch_p(T_DIVIDE)
- >> unary_exp_nocalc
- | ch_p(T_PERCENT)
- >> unary_exp_nocalc
- )
- ;
- unary_exp_nocalc
- = primary_exp_nocalc
- | ch_p(T_PLUS) >> unary_exp_nocalc
- | ch_p(T_MINUS) >> unary_exp_nocalc
- | pattern_p(T_COMPL, MainTokenMask) >> unary_exp_nocalc
- | pattern_p(T_NOT, MainTokenMask) >> unary_exp_nocalc
- ;
- primary_exp_nocalc
- = constant_nocalc
- | ch_p(T_LEFTPAREN)
- >> const_exp_nocalc
- >> ch_p(T_RIGHTPAREN)
- ;
- constant_nocalc
- = ch_p(T_PP_NUMBER)
- | ch_p(T_INTLIT)
- | ch_p(T_LONGINTLIT)
- | ch_p(T_CHARLIT)
- ;
- BOOST_SPIRIT_DEBUG_TRACE_RULE(pp_expression, TRACE_CPP_EXPR_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(const_exp, TRACE_CPP_EXPR_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(logical_or_exp, TRACE_CPP_EXPR_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(logical_and_exp, TRACE_CPP_EXPR_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(inclusive_or_exp, TRACE_CPP_EXPR_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(exclusive_or_exp, TRACE_CPP_EXPR_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(and_exp, TRACE_CPP_EXPR_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(cmp_equality, TRACE_CPP_EXPR_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(cmp_relational, TRACE_CPP_EXPR_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(shift_exp, TRACE_CPP_EXPR_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(add_exp, TRACE_CPP_EXPR_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(multiply_exp, TRACE_CPP_EXPR_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(unary_exp, TRACE_CPP_EXPR_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(primary_exp, TRACE_CPP_EXPR_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(constant, TRACE_CPP_EXPR_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(const_exp_subrule, TRACE_CPP_EXPR_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(const_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(logical_or_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(logical_and_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(inclusive_or_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(exclusive_or_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(and_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(cmp_equality_nocalc, TRACE_CPP_EXPR_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(cmp_relational_nocalc, TRACE_CPP_EXPR_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(shift_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(add_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(multiply_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(unary_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(primary_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(constant_nocalc, TRACE_CPP_EXPR_GRAMMAR);
- }
- // start rule of this grammar
- simple_rule_t const& start() const
- { return pp_expression; }
- };
- };
- ///////////////////////////////////////////////////////////////////////////////
- #undef TRACE_CPP_EXPR_GRAMMAR
- ///////////////////////////////////////////////////////////////////////////////
- //
- // The following function is defined here, to allow the separation of
- // the compilation of the expression_grammar from the function using it.
- //
- ///////////////////////////////////////////////////////////////////////////////
- #if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
- #define BOOST_WAVE_EXPRGRAMMAR_GEN_INLINE
- #else
- #define BOOST_WAVE_EXPRGRAMMAR_GEN_INLINE inline
- #endif
- template <typename TokenT>
- BOOST_WAVE_EXPRGRAMMAR_GEN_INLINE
- bool
- expression_grammar_gen<TokenT>::evaluate(
- typename token_sequence_type::const_iterator const &first,
- typename token_sequence_type::const_iterator const &last,
- typename token_type::position_type const &act_pos,
- bool if_block_status, value_error &status)
- {
- using namespace boost::spirit::classic;
- using namespace boost::wave;
- using namespace boost::wave::grammars::closures;
- using boost::wave::util::impl::as_string;
- typedef typename token_sequence_type::const_iterator iterator_type;
- typedef typename token_sequence_type::value_type::string_type string_type;
- parse_info<iterator_type> hit(first);
- closure_value result; // expression result
- #if !defined(BOOST_NO_EXCEPTIONS)
- try
- #endif
- {
- expression_grammar g; // expression grammar
- hit = parse (first, last, g[spirit_assign_actor(result)],
- ch_p(T_SPACE) | ch_p(T_CCOMMENT) | ch_p(T_CPPCOMMENT));
- if (!hit.hit) {
- // expression is illformed
- if (if_block_status) {
- string_type expression = as_string<string_type>(first, last);
- if (0 == expression.size())
- expression = "<empty expression>";
- BOOST_WAVE_THROW(preprocess_exception, ill_formed_expression,
- expression.c_str(), act_pos);
- return false;
- }
- else {
- // as the if_block_status is false no errors will be reported
- return false;
- }
- }
- }
- #if !defined(BOOST_NO_EXCEPTIONS)
- catch (boost::wave::preprocess_exception const& e) {
- // expression is illformed
- if (if_block_status) {
- boost::throw_exception(e);
- return false;
- }
- else {
- // as the if_block_status is false no errors will be reported
- return false;
- }
- }
- #endif
- if (!hit.full) {
- // The token list starts with a valid expression, but there remains
- // something. If the remainder consists out of whitespace only, the
- // expression is still valid.
- iterator_type next = hit.stop;
- while (next != last) {
- switch (token_id(*next)) {
- case T_SPACE:
- case T_SPACE2:
- case T_CCOMMENT:
- break; // ok continue
- case T_NEWLINE:
- case T_EOF:
- case T_CPPCOMMENT: // contains newline
- return as_bool(result); // expression is valid
- default:
- // expression is illformed
- if (if_block_status) {
- string_type expression = as_string<string_type>(first, last);
- if (0 == expression.size())
- expression = "<empty expression>";
- BOOST_WAVE_THROW(preprocess_exception, ill_formed_expression,
- expression.c_str(), act_pos);
- return false;
- }
- else {
- // as the if_block_status is false no errors will be reported
- return false;
- }
- }
- ++next;
- }
- }
- if (error_noerror != result.is_valid()) // division or other error by zero occurred
- status = result.is_valid();
- // token sequence is a valid expression
- return as_bool(result);
- }
- #undef BOOST_WAVE_EXPRGRAMMAR_GEN_INLINE
- ///////////////////////////////////////////////////////////////////////////////
- } // namespace grammars
- } // namespace wave
- } // namespace boost
- // the suffix header occurs after all of the code
- #ifdef BOOST_HAS_ABI_HEADERS
- #include BOOST_ABI_SUFFIX
- #endif
- #endif // !defined(BOOST_CPP_EXPRESSION_GRAMMAR_HPP_099CD1A4_A6C0_44BE_8F24_0B00F5BE5674_INCLUDED)
|