📄 cpp_expression_grammar.hpp
字号:
[
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 = !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_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_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)
{
using namespace boost::spirit;
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
try {
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);
}
else {
// as the if_block_status is false no errors will be reported
return false;
}
}
}
catch (wave::preprocess_exception const& e) {
// expression is illformed
if (if_block_status) {
throw e;
}
else {
// as the if_block_status is false no errors will be reported
return false;
}
}
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 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);
}
else {
// as the if_block_status is false no errors will be reported
return false;
}
}
++next;
}
}
if (closure_value::error_noerror != result.is_valid()) {
// division by zero occured
string_type expression = as_string<string_type>(first, last);
if (0 == expression.size())
expression = "empty expression";
if (closure_value::error_division_by_zero == result.is_valid()) {
BOOST_WAVE_THROW(preprocess_exception, division_by_zero,
expression.c_str(), act_pos);
}
else if (closure_value::error_overflow == result.is_valid()) {
BOOST_WAVE_THROW(preprocess_exception, integer_overflow,
expression.c_str(), act_pos);
}
}
// token sequence is a valid expression
return bool(result);
}
#undef BOOST_WAVE_EXPRGRAMMAR_GEN_INLINE
///////////////////////////////////////////////////////////////////////////////
} // namespace grammars
} // namespace wave
} // namespace boost
#endif // !defined(CPP_EXPRESSION_GRAMMAR_HPP_099CD1A4_A6C0_44BE_8F24_0B00F5BE5674_INCLUDED)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -