Added boost header
This commit is contained in:
870
test/external/boost/wave/grammars/cpp_expression_grammar.hpp
vendored
Normal file
870
test/external/boost/wave/grammars/cpp_expression_grammar.hpp
vendored
Normal file
@@ -0,0 +1,870 @@
|
||||
/*=============================================================================
|
||||
Boost.Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://www.boost.org/
|
||||
|
||||
Copyright (c) 2001-2011 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(CPP_EXPRESSION_GRAMMAR_HPP_099CD1A4_A6C0_44BE_8F24_0B00F5BE5674_INCLUDED)
|
||||
#define 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_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_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 (static_cast<unsigned int>(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(CPP_EXPRESSION_GRAMMAR_HPP_099CD1A4_A6C0_44BE_8F24_0B00F5BE5674_INCLUDED)
|
||||
Reference in New Issue
Block a user