Back to home page

EIC code displayed by LXR

 
 

    


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

0001 /*=============================================================================
0002     Boost.Wave: A Standard compliant C++ preprocessor library
0003 
0004     http://www.boost.org/
0005 
0006     Copyright (c) 2020      Jeff Trull
0007     Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost
0008     Software License, Version 1.0. (See accompanying file
0009     LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0010 =============================================================================*/
0011 
0012 #if !defined(BOOST_CPP_HAS_INCLUDE_GRAMMAR_HPP_F48287B2_DC67_40A8_B4A1_800EFBD67869_INCLUDED)
0013 #define BOOST_CPP_HAS_INCLUDE_GRAMMAR_HPP_F48287B2_DC67_40A8_B4A1_800EFBD67869_INCLUDED
0014 
0015 #include <boost/wave/wave_config.hpp>
0016 
0017 #include <boost/assert.hpp>
0018 #include <boost/spirit/include/classic_core.hpp>
0019 #include <boost/spirit/include/classic_closure.hpp>
0020 #include <boost/spirit/include/classic_assign_actor.hpp>
0021 #include <boost/spirit/include/classic_push_back_actor.hpp>
0022 
0023 #include <boost/wave/token_ids.hpp>
0024 #include <boost/wave/util/pattern_parser.hpp>
0025 #include <boost/wave/grammars/cpp_has_include_grammar_gen.hpp>
0026 
0027 #if !defined(spirit_append_actor)
0028 #define spirit_append_actor(actor) boost::spirit::classic::push_back_a(actor)
0029 #endif // !has_include(spirit_append_actor)
0030 
0031 // this must occur after all of the includes and before any code appears
0032 #ifdef BOOST_HAS_ABI_HEADERS
0033 #include BOOST_ABI_PREFIX
0034 #endif
0035 
0036 ///////////////////////////////////////////////////////////////////////////////
0037 namespace boost {
0038 namespace wave {
0039 namespace grammars {
0040 
0041 ///////////////////////////////////////////////////////////////////////////////
0042 //  define, whether the rule's should generate some debug output
0043 #define TRACE_CPP_HAS_INCLUDE_GRAMMAR \
0044     bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_HAS_INCLUDE_GRAMMAR) \
0045     /**/
0046 
0047 template <typename ContainerT>
0048 struct has_include_grammar :
0049     public boost::spirit::classic::grammar<has_include_grammar<ContainerT> >
0050 {
0051     has_include_grammar(ContainerT &tokens_seq_,
0052                         bool &is_quoted_filename_,
0053                         bool &is_system_)
0054     :   tokens_seq(tokens_seq_), is_quoted_filename(is_quoted_filename_),
0055         is_system(is_system_), true_(true)
0056     {
0057         BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this, "has_include_grammar",
0058             TRACE_CPP_HAS_INCLUDE_GRAMMAR);
0059         is_quoted_filename = false;
0060         is_system = false;
0061     }
0062 
0063     template <typename ScannerT>
0064     struct definition
0065     {
0066         typedef boost::spirit::classic::rule<ScannerT> rule_t;
0067 
0068         rule_t has_include_op;
0069         rule_t system_include;
0070         rule_t nonsystem_include;
0071 
0072         rule_t nonparen;
0073         rule_t parenthesized_exp;
0074         rule_t computed_include;
0075 
0076         definition(has_include_grammar const & self)
0077         {
0078             using namespace boost::spirit::classic;
0079             using namespace boost::wave;
0080             using namespace boost::wave::util;
0081 
0082             has_include_op
0083                 =   ch_p(T_IDENTIFIER) >>     // token contains '__has_include'
0084                     ch_p(T_LEFTPAREN)  >>
0085                     (system_include | nonsystem_include | computed_include) >>
0086                     ch_p(T_RIGHTPAREN)
0087                 ;
0088 
0089             system_include
0090                 = ch_p(T_LESS)
0091                 [
0092                     spirit_append_actor(self.tokens_seq)
0093                 ]
0094                 >> * (~ch_p(T_GREATER))
0095                 [
0096                     spirit_append_actor(self.tokens_seq)
0097                 ]
0098                 >> ch_p(T_GREATER)
0099                 [
0100                     spirit_append_actor(self.tokens_seq)
0101                 ][
0102                     assign_a(self.is_quoted_filename, self.true_)
0103                 ][
0104                     assign_a(self.is_system, self.true_)
0105                 ]
0106                 ;
0107 
0108             nonsystem_include = ch_p(T_STRINGLIT)
0109                 [
0110                     spirit_append_actor(self.tokens_seq)
0111                 ][
0112                     assign_a(self.is_quoted_filename, self.true_)
0113                 ]
0114                 ;
0115 
0116             // an action to store a sequence of parsed tokens
0117             auto append_seq = [&](typename ScannerT::iterator_t first,
0118                                   typename ScannerT::iterator_t last) {
0119                 for (;first != last;++first) {
0120                     self.tokens_seq.push_back(*first);
0121                 };
0122             };
0123 
0124             // if neither of the above match we take everything between
0125             // the parentheses and evaluate it ("computed include")
0126             // supported expressions are "implementation defined" per the gcc manual
0127             // we've tried to be fairly generous in Wave
0128             // here we accept any set of non-whitespace characters with
0129             // properly nested parentheses:
0130             nonparen = (anychar_p - ch_p(T_LEFTPAREN) - ch_p(T_RIGHTPAREN)) [ append_seq ] ;
0131 
0132             parenthesized_exp =
0133                         ch_p(T_LEFTPAREN)[ spirit_append_actor(self.tokens_seq) ] >>
0134                         computed_include >>
0135                         ch_p(T_RIGHTPAREN)[ spirit_append_actor(self.tokens_seq) ] ;
0136             computed_include = * (nonparen | parenthesized_exp) ;
0137 
0138 
0139             BOOST_SPIRIT_DEBUG_TRACE_RULE(has_include_op, TRACE_CPP_HAS_INCLUDE_GRAMMAR);
0140             BOOST_SPIRIT_DEBUG_TRACE_RULE(system_include, TRACE_CPP_HAS_INCLUDE_GRAMMAR);
0141             BOOST_SPIRIT_DEBUG_TRACE_RULE(nonsystem_include, TRACE_CPP_HAS_INCLUDE_GRAMMAR);
0142             BOOST_SPIRIT_DEBUG_TRACE_RULE(computed_include, TRACE_CPP_HAS_INCLUDE_GRAMMAR);
0143             BOOST_SPIRIT_DEBUG_TRACE_RULE(parenthesized_exp, TRACE_CPP_HAS_INCLUDE_GRAMMAR);
0144             BOOST_SPIRIT_DEBUG_TRACE_RULE(nonparen, TRACE_CPP_HAS_INCLUDE_GRAMMAR);
0145         }
0146 
0147         // start rule of this grammar
0148         rule_t const& start() const
0149         { return has_include_op; }
0150     };
0151 
0152     ContainerT &tokens_seq;
0153     bool &is_quoted_filename;
0154     bool &is_system;
0155     const bool true_;  // Spirit Classic actors operate on references, not values
0156 };
0157 
0158 ///////////////////////////////////////////////////////////////////////////////
0159 #undef TRACE_CPP_HAS_INCLUDE_GRAMMAR
0160 
0161 ///////////////////////////////////////////////////////////////////////////////
0162 //
0163 //  The following parse function is has_include here, to allow the separation of
0164 //  the compilation of the has_include_grammar from the function
0165 //  using it.
0166 //
0167 ///////////////////////////////////////////////////////////////////////////////
0168 
0169 #if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
0170 #define BOOST_WAVE_HAS_INCLUDE_GRAMMAR_GEN_INLINE
0171 #else
0172 #define BOOST_WAVE_HAS_INCLUDE_GRAMMAR_GEN_INLINE inline
0173 #endif
0174 
0175 //  The parse_operator_define function is instantiated manually twice to
0176 //  simplify the explicit specialization of this template. This way the user
0177 //  has only to specify one template parameter (the lexer type) to correctly
0178 //  formulate the required explicit specialization.
0179 //  This results in no code overhead, because otherwise the function would be
0180 //  generated by the compiler twice anyway.
0181 
0182 template <typename LexIteratorT>
0183 BOOST_WAVE_HAS_INCLUDE_GRAMMAR_GEN_INLINE
0184 boost::spirit::classic::parse_info<
0185     typename has_include_grammar_gen<LexIteratorT>::iterator1_type
0186 >
0187 has_include_grammar_gen<LexIteratorT>::parse_operator_has_include (
0188     iterator1_type const &first, iterator1_type const &last,
0189     token_sequence_type &tokens,
0190     bool &is_quoted_filename, bool &is_system)
0191 {
0192     using namespace boost::spirit::classic;
0193     using namespace boost::wave;
0194 
0195     has_include_grammar<token_sequence_type>
0196         g(tokens, is_quoted_filename, is_system);
0197     return boost::spirit::classic::parse (
0198         first, last, g, ch_p(T_SPACE) | ch_p(T_CCOMMENT));
0199 }
0200 
0201 template <typename LexIteratorT>
0202 BOOST_WAVE_HAS_INCLUDE_GRAMMAR_GEN_INLINE
0203 boost::spirit::classic::parse_info<
0204     typename has_include_grammar_gen<LexIteratorT>::iterator2_type
0205 >
0206 has_include_grammar_gen<LexIteratorT>::parse_operator_has_include (
0207     iterator2_type const &first, iterator2_type const &last,
0208     token_sequence_type &found_qualified_name,
0209     bool &is_quoted_filename, bool &is_system)
0210 {
0211     using namespace boost::spirit::classic;
0212     using namespace boost::wave;
0213 
0214     has_include_grammar<token_sequence_type>
0215         g(found_qualified_name, is_quoted_filename, is_system);
0216     return boost::spirit::classic::parse (
0217         first, last, g, ch_p(T_SPACE) | ch_p(T_CCOMMENT));
0218 }
0219 
0220 #undef BOOST_WAVE_HAS_INCLUDE_GRAMMAR_GEN_INLINE
0221 
0222 ///////////////////////////////////////////////////////////////////////////////
0223 }   // namespace grammars
0224 }   // namespace wave
0225 }   // namespace boost
0226 
0227 // the suffix header occurs after all of the code
0228 #ifdef BOOST_HAS_ABI_HEADERS
0229 #include BOOST_ABI_SUFFIX
0230 #endif
0231 
0232 #endif // !defined(BOOST_CPP_HAS_INCLUDE_GRAMMAR_HPP_F48287B2_DC67_40A8_B4A1_800EFBD67869_INCLUDED)