cpp_iterator.hpp

来自「support vector clustering for vc++」· HPP 代码 · 共 1,705 行 · 第 1/5 页

HPP
1,705
字号
                        macroname.get_value().c_str(), (*pit).get_position());
                }
            }
            
        // if there wasn't an ellipsis, then there shouldn't be a __VA_ARGS__ 
        // placeholder in the definition too [C99 Standard 6.10.3.5]
            if (!seen_ellipses) {
                typedef typename token_sequence_type::iterator definition_iterator_t;

                bool seen_va_args = false;
                definition_iterator_t pend = macrodefinition.end();
                for (definition_iterator_t dit = macrodefinition.begin(); 
                     dit != pend; ++dit) 
                {
                    if (T_IDENTIFIER == token_id(*dit) && 
                        "__VA_ARGS__" == (*dit).get_value())
                    {
                        seen_va_args = true;
                    }
                }
                if (seen_va_args) {
                // must not have seen __VA_ARGS__ placeholder
                    BOOST_WAVE_THROW(preprocess_exception, bad_define_statement_va_args, 
                        macroname.get_value().c_str(), act_token.get_position());
                }
            }
        }
        else
#endif // BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
        {
        // test, that there is no T_ELLIPSES given
            using namespace cpplexer;
            typedef typename std::vector<result_type>::iterator 
                parameter_iterator_t;
            
            parameter_iterator_t end = macroparameters.end();
            for (parameter_iterator_t pit = macroparameters.begin(); 
                pit != end; ++pit) 
            {
                if (T_ELLIPSIS == token_id(*pit)) {
                // if variadics are disabled, no ellipses should be given
                    BOOST_WAVE_THROW(preprocess_exception, bad_define_statement, 
                        macroname.get_value().c_str(), (*pit).get_position());
                }
            }
        }
    }
    
// add the new macro to the macromap
    ctx.add_macro_definition(macroname, has_parameters, macroparameters, 
        macrodefinition);
}

///////////////////////////////////////////////////////////////////////////////
//  
//  on_undefine(): handle #undef directives
//
///////////////////////////////////////////////////////////////////////////////
template <typename ContextT> 
inline void  
pp_iterator_functor<ContextT>::on_undefine (result_type const &token) 
{
    BOOST_ASSERT(ctx.get_if_block_status());

// retrieve the macro name to undefine from the parse tree
    ctx.remove_macro_definition(token.get_value()); // throws for predefined macros
}

///////////////////////////////////////////////////////////////////////////////
//  
//  on_ifdef(): handle #ifdef directives
//
///////////////////////////////////////////////////////////////////////////////
template <typename ContextT> 
inline void  
pp_iterator_functor<ContextT>::on_ifdef(
    typename parse_tree_type::const_iterator const &begin,
    typename parse_tree_type::const_iterator const &end)
{
get_token_value<result_type, parse_node_type> get_value;
token_sequence_type toexpand;

    std::copy(make_ref_transform_iterator((*begin).children.begin(), get_value), 
        make_ref_transform_iterator((*begin).children.end(), get_value),
        std::inserter(toexpand, toexpand.end()));

bool is_defined = ctx.is_defined_macro(toexpand.begin(), toexpand.end());

    ctx.get_hooks().evaluated_conditional_expression(toexpand, is_defined);
    ctx.enter_if_block(is_defined);
}

///////////////////////////////////////////////////////////////////////////////
//  
//  on_ifndef(): handle #ifndef directives
//
///////////////////////////////////////////////////////////////////////////////
template <typename ContextT> 
inline void  
pp_iterator_functor<ContextT>::on_ifndef(
    typename parse_tree_type::const_iterator const &begin,
    typename parse_tree_type::const_iterator const &end)
{
get_token_value<result_type, parse_node_type> get_value;
token_sequence_type toexpand;

    std::copy(make_ref_transform_iterator((*begin).children.begin(), get_value), 
        make_ref_transform_iterator((*begin).children.end(), get_value),
        std::inserter(toexpand, toexpand.end()));

bool is_defined = ctx.is_defined_macro(toexpand.begin(), toexpand.end());

    ctx.get_hooks().evaluated_conditional_expression(toexpand, is_defined);
    ctx.enter_if_block(!is_defined);
}

///////////////////////////////////////////////////////////////////////////////
//  
//  on_else(): handle #else directives
//
///////////////////////////////////////////////////////////////////////////////
template <typename ContextT> 
inline void  
pp_iterator_functor<ContextT>::on_else()
{
    if (!ctx.enter_else_block()) {
    // #else without matching #if
        BOOST_WAVE_THROW(preprocess_exception, missing_matching_if, "#else", 
            act_pos);
    }
}

///////////////////////////////////////////////////////////////////////////////
//  
//  on_endif(): handle #endif directives
//
///////////////////////////////////////////////////////////////////////////////
template <typename ContextT> 
inline void  
pp_iterator_functor<ContextT>::on_endif()
{
    if (!ctx.exit_if_block()) {
    // #endif without matching #if
        BOOST_WAVE_THROW(preprocess_exception, missing_matching_if, "#endif", 
            act_pos);
    }
}

///////////////////////////////////////////////////////////////////////////////
//  
//  on_if(): handle #if directives
//
///////////////////////////////////////////////////////////////////////////////
template <typename ContextT> 
inline void  
pp_iterator_functor<ContextT>::on_if(
    typename parse_tree_type::const_iterator const &begin,
    typename parse_tree_type::const_iterator const &end)
{
// preprocess the given sequence into the provided list
get_token_value<result_type, parse_node_type> get_value;
token_sequence_type expanded;
token_sequence_type toexpand;

    std::copy(make_ref_transform_iterator(begin, get_value), 
        make_ref_transform_iterator(end, get_value),
        std::inserter(toexpand, toexpand.end()));

    typename token_sequence_type::iterator begin2 = toexpand.begin();
    ctx.expand_whole_tokensequence(begin2, toexpand.end(), expanded);

// replace all remaining (== undefined) identifiers with an integer literal '0'
    typename token_sequence_type::iterator exp_end = expanded.end();
    for (typename token_sequence_type::iterator exp_it = expanded.begin();
         exp_it != exp_end; ++exp_it)
    {
        using namespace boost::wave;
        
        token_id id = token_id(*exp_it);
        if (IS_CATEGORY(id, IdentifierTokenType) ||
            IS_CATEGORY(id, KeywordTokenType))
        {
            (*exp_it).set_token_id(T_INTLIT);
            (*exp_it).set_value("0");
        }
    }
    
#if BOOST_WAVE_DUMP_CONDITIONAL_EXPRESSIONS != 0
    {
        string_type outstr(boost::wave::util::impl::as_string(toexpand));
        outstr += "(" + boost::wave::util::impl::as_string(expanded) + ")";
        BOOST_WAVE_DUMP_CONDITIONAL_EXPRESSIONS_OUT << "#if " << outstr 
            << std::endl;
    }
#endif

// parse the expression and enter the #if block
grammars::value_error status = grammars::error_noerror;
bool if_status = grammars::expression_grammar_gen<result_type>::
            evaluate(expanded.begin(), expanded.end(), act_pos,
                ctx.get_if_block_status(), status);
                
    ctx.get_hooks().evaluated_conditional_expression(toexpand, if_status);
    if (grammars::error_noerror != status) {
    // division or other error by zero occurred
        string_type expression = util::impl::as_string(expanded);
        if (0 == expression.size()) 
            expression = "<empty expression>";
            
        if (grammars::error_division_by_zero & status) {
            BOOST_WAVE_THROW(preprocess_exception, division_by_zero, 
                expression.c_str(), act_pos);
        }
        if (grammars::error_integer_overflow & status) {
        // we may validly continue 
            ctx.enter_if_block(if_status);
            BOOST_WAVE_THROW(preprocess_exception, integer_overflow, 
                expression.c_str(), act_pos);
            return;
        }
        if (grammars::error_character_overflow & status) {
        // we may validly continue 
            ctx.enter_if_block(if_status);
            BOOST_WAVE_THROW(preprocess_exception, 
                character_literal_out_of_range, expression.c_str(), act_pos);
            return;
        }
    }

    ctx.enter_if_block(if_status);
}

///////////////////////////////////////////////////////////////////////////////
//  
//  on_elif(): handle #elif directives
//
///////////////////////////////////////////////////////////////////////////////
template <typename ContextT> 
inline void  
pp_iterator_functor<ContextT>::on_elif(
    typename parse_tree_type::const_iterator const &begin,
    typename parse_tree_type::const_iterator const &end,
    token_sequence_type const& found_eoltokens)
{
// preprocess the given sequence into the provided list
get_token_value<result_type, parse_node_type> get_value;
token_sequence_type toexpand;

    std::copy(make_ref_transform_iterator(begin, get_value), 
        make_ref_transform_iterator(end, get_value),
        std::inserter(toexpand, toexpand.end()));

// check current if block status
    if (ctx.get_if_block_some_part_status()) {
        if (!ctx.enter_elif_block(false)) {
        // #else without matching #if
            BOOST_WAVE_THROW(preprocess_exception, missing_matching_if, "#elif", 
                act_pos);
        }

    // skip all the expression and the trailing whitespace
    typename token_sequence_type::iterator begin2 = toexpand.begin();
    typename token_sequence_type::const_iterator begin3 = found_eoltokens.begin();

        impl::skip_to_eol(ctx, begin2, toexpand.end());
        impl::skip_to_eol(ctx, begin3, found_eoltokens.end());
        return;     // one of previous #if/#elif was true, so don't enter this #elif 
    }
            
// preprocess the given sequence into the provided list
token_sequence_type expanded;

    typename token_sequence_type::iterator begin2 = toexpand.begin();
    ctx.expand_whole_tokensequence(begin2, toexpand.end(), expanded);
    
// replace all remaining (== undefined) identifiers with an integer literal '0'
    typename token_sequence_type::iterator exp_end = expanded.end();
    for (typename token_sequence_type::iterator exp_it = expanded.begin();
         exp_it != exp_end; ++exp_it)
    {
        using namespace boost::wave;
        
        token_id id = token_id(*exp_it);
        if (IS_CATEGORY(id, IdentifierTokenType) ||
            IS_CATEGORY(id, KeywordTokenType))
        {
            (*exp_it).set_token_id(T_INTLIT);
            (*exp_it).set_value("0");
        }
    }

#if BOOST_WAVE_DUMP_CONDITIONAL_EXPRESSIONS != 0
    {
        string_type outstr(boost::wave::util::impl::as_string(toexpand));
        outstr += "(" + boost::wave::util::impl::as_string(expanded) + ")";
        BOOST_WAVE_DUMP_CONDITIONAL_EXPRESSIONS_OUT << "#elif " << outstr << std::endl;
    }
#endif

// parse the expression and enter the #elif block
grammars::value_error status = grammars::error_noerror;
bool if_status = grammars::expression_grammar_gen<result_type>::
            evaluate(expanded.begin(), expanded.end(), act_pos,
                ctx.get_if_block_status(), status);
                
    ctx.get_hooks().evaluated_conditional_expression(toexpand, if_status);
    if (grammars::error_noerror != status) {
    // division or other error by zero occurred
        string_type expression = util::impl::as_string(expanded);
        if (0 == expression.size()) 
            expression = "<empty expression>";
            
        if (grammars::error_division_by_zero & status) {
            BOOST_WAVE_THROW(preprocess_exception, division_by_zero, 
                expression.c_str(), act_pos);
        }
        if (grammars::error_integer_overflow & status) {
        // we validly may continue
            if (!ctx.enter_elif_block(if_status)) { 
            // #elif without matching #if
                BOOST_WAVE_THROW(preprocess_exception, missing_matching_if, 
                    "#elif", act_pos);
            }
            BOOST_WAVE_THROW(preprocess_exception, integer_overflow,
                expression.c_str(), act_pos);
            return;
        }
        if (grammars::error_character_overflow & status) {
        // we validly may continue
            if (!ctx.enter_elif_block(if_status)) { 
            // #elif without matching #if
                BOOST_WAVE_THROW(preprocess_exception, missing_matching_if, 
                    "#elif", act_pos);
            }
            BOOST_WAVE_THROW(preprocess_exception, 
                character_literal_out_of_range, expression.c_str(), act_pos);
            return;
        }
    }

    if (!ctx.enter_elif_block(if_s

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?