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) 2001-2012 Hartmut Kaiser. Distributed under the Boost
0007     Software License, Version 1.0. (See accompanying file
0008     LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0009 =============================================================================*/
0010 
0011 #if !defined(BOOST_CPP_GRAMMAR_HPP_FEAEBC2E_2734_428B_A7CA_85E5A415E23E_INCLUDED)
0012 #define BOOST_CPP_GRAMMAR_HPP_FEAEBC2E_2734_428B_A7CA_85E5A415E23E_INCLUDED
0013 
0014 #include <boost/spirit/include/classic_core.hpp>
0015 #include <boost/spirit/include/classic_parse_tree.hpp>
0016 #include <boost/spirit/include/classic_parse_tree_utils.hpp>
0017 #include <boost/spirit/include/classic_confix.hpp>
0018 #include <boost/spirit/include/classic_lists.hpp>
0019 
0020 #include <boost/wave/wave_config.hpp>
0021 #include <boost/pool/pool_alloc.hpp>
0022 
0023 #if BOOST_WAVE_DUMP_PARSE_TREE != 0
0024 #include <map>
0025 #include <boost/spirit/include/classic_tree_to_xml.hpp>
0026 #endif
0027 
0028 #include <boost/wave/token_ids.hpp>
0029 #include <boost/wave/grammars/cpp_grammar_gen.hpp>
0030 #include <boost/wave/util/pattern_parser.hpp>
0031 
0032 #include <boost/wave/cpp_exceptions.hpp>
0033 
0034 // this must occur after all of the includes and before any code appears
0035 #ifdef BOOST_HAS_ABI_HEADERS
0036 #include BOOST_ABI_PREFIX
0037 #endif
0038 
0039 ///////////////////////////////////////////////////////////////////////////////
0040 namespace boost {
0041 namespace wave {
0042 namespace grammars {
0043 
0044 namespace impl {
0045 
0046 ///////////////////////////////////////////////////////////////////////////////
0047 //
0048 //  store_found_eof
0049 //
0050 //      The store_found_eof functor sets a given flag if the T_EOF token was
0051 //      found during the parsing process
0052 //
0053 ///////////////////////////////////////////////////////////////////////////////
0054 
0055     struct store_found_eof {
0056 
0057         store_found_eof(bool &found_eof_) : found_eof(found_eof_) {}
0058 
0059         template <typename TokenT>
0060         void operator()(TokenT const &/*token*/) const
0061         {
0062             found_eof = true;
0063         }
0064 
0065         bool &found_eof;
0066     };
0067 
0068 ///////////////////////////////////////////////////////////////////////////////
0069 //
0070 //  store_found_directive
0071 //
0072 //      The store_found_directive functor stores the token_id of the recognized
0073 //      pp directive
0074 //
0075 ///////////////////////////////////////////////////////////////////////////////
0076 
0077     template <typename TokenT>
0078     struct store_found_directive {
0079 
0080         store_found_directive(TokenT &found_directive_)
0081         :   found_directive(found_directive_) {}
0082 
0083         void operator()(TokenT const &token) const
0084         {
0085             found_directive = token;
0086         }
0087 
0088         TokenT &found_directive;
0089     };
0090 
0091 ///////////////////////////////////////////////////////////////////////////////
0092 //
0093 //  store_found_eoltokens
0094 //
0095 //      The store_found_eoltokens functor stores the token sequence of the
0096 //      line ending for a particular pp directive
0097 //
0098 ///////////////////////////////////////////////////////////////////////////////
0099 
0100     template <typename ContainerT>
0101     struct store_found_eoltokens {
0102 
0103         store_found_eoltokens(ContainerT &found_eoltokens_)
0104         :   found_eoltokens(found_eoltokens_) {}
0105 
0106         template <typename IteratorT>
0107         void operator()(IteratorT const &first, IteratorT const& last) const
0108         {
0109             std::copy(first, last,
0110                 std::inserter(found_eoltokens, found_eoltokens.end()));
0111         }
0112 
0113         ContainerT &found_eoltokens;
0114     };
0115 
0116 ///////////////////////////////////////////////////////////////////////////////
0117 //
0118 //  flush_underlying_parser
0119 //
0120 //      The flush_underlying_parser flushes the underlying
0121 //      multi_pass_iterator during the normal parsing process. This is
0122 //      used at certain points during the parsing process, when it is
0123 //      clear, that no backtracking is needed anymore and the input
0124 //      gathered so far may be discarded.
0125 //
0126 ///////////////////////////////////////////////////////////////////////////////
0127     struct flush_underlying_parser
0128     :   public boost::spirit::classic::parser<flush_underlying_parser>
0129     {
0130         typedef flush_underlying_parser this_t;
0131 
0132         template <typename ScannerT>
0133         typename boost::spirit::classic::parser_result<this_t, ScannerT>::type
0134         parse(ScannerT const& scan) const
0135         {
0136             scan.first.clear_queue();
0137             return scan.empty_match();
0138         }
0139     };
0140 
0141     flush_underlying_parser const
0142         flush_underlying_parser_p = flush_underlying_parser();
0143 
0144 }   // anonymous namespace
0145 
0146 ///////////////////////////////////////////////////////////////////////////////
0147 //  define, whether the rule's should generate some debug output
0148 #define TRACE_CPP_GRAMMAR \
0149     bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_CPP_GRAMMAR) \
0150     /**/
0151 
0152 ///////////////////////////////////////////////////////////////////////////////
0153 // Encapsulation of the C++ preprocessor grammar.
0154 template <typename TokenT, typename ContainerT>
0155 struct cpp_grammar :
0156     public boost::spirit::classic::grammar<cpp_grammar<TokenT, ContainerT> >
0157 {
0158     typedef typename TokenT::position_type  position_type;
0159     typedef cpp_grammar<TokenT, ContainerT> grammar_type;
0160     typedef impl::store_found_eof           store_found_eof_type;
0161     typedef impl::store_found_directive<TokenT>     store_found_directive_type;
0162     typedef impl::store_found_eoltokens<ContainerT> store_found_eoltokens_type;
0163 
0164     template <typename ScannerT>
0165     struct definition
0166     {
0167         // non-parse_tree generating rule type
0168         typedef typename ScannerT::iteration_policy_t iteration_policy_t;
0169         typedef boost::spirit::classic::match_policy match_policy_t;
0170         typedef typename ScannerT::action_policy_t action_policy_t;
0171         typedef
0172             boost::spirit::classic::scanner_policies<
0173                 iteration_policy_t, match_policy_t, action_policy_t>
0174             policies_t;
0175         typedef
0176             boost::spirit::classic::scanner<typename ScannerT::iterator_t, policies_t>
0177             non_tree_scanner_t;
0178         typedef
0179             boost::spirit::classic::rule<
0180                 non_tree_scanner_t, boost::spirit::classic::dynamic_parser_tag>
0181             no_tree_rule_type;
0182 
0183         // 'normal' (parse_tree generating) rule type
0184         typedef
0185             boost::spirit::classic::rule<
0186                 ScannerT, boost::spirit::classic::dynamic_parser_tag>
0187             rule_type;
0188 
0189         rule_type pp_statement, macro_include_file;
0190 //         rule_type include_file, system_include_file;
0191         rule_type plain_define, macro_definition, macro_parameters;
0192         rule_type undefine;
0193         rule_type ppifdef, ppifndef, ppif, ppelif;
0194 //         rule_type ppelse, ppendif;
0195         rule_type ppline;
0196         rule_type pperror;
0197         rule_type ppwarning;
0198         rule_type pppragma;
0199         rule_type illformed;
0200         rule_type ppqualifiedname;
0201         rule_type eol_tokens;
0202         no_tree_rule_type ppsp;
0203 #if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
0204         rule_type ppregion;
0205         rule_type ppendregion;
0206 #endif
0207 
0208         definition(cpp_grammar const &self)
0209         {
0210             // import the spirit and cpplexer namespaces here
0211             using namespace boost::spirit::classic;
0212             using namespace boost::wave;
0213             using namespace boost::wave::util;
0214 
0215             // set the rule id's for later use
0216             pp_statement.set_id(BOOST_WAVE_PP_STATEMENT_ID);
0217 //             include_file.set_id(BOOST_WAVE_INCLUDE_FILE_ID);
0218 //             system_include_file.set_id(BOOST_WAVE_SYSINCLUDE_FILE_ID);
0219             macro_include_file.set_id(BOOST_WAVE_MACROINCLUDE_FILE_ID);
0220             plain_define.set_id(BOOST_WAVE_PLAIN_DEFINE_ID);
0221             macro_parameters.set_id(BOOST_WAVE_MACRO_PARAMETERS_ID);
0222             macro_definition.set_id(BOOST_WAVE_MACRO_DEFINITION_ID);
0223             undefine.set_id(BOOST_WAVE_UNDEFINE_ID);
0224             ppifdef.set_id(BOOST_WAVE_IFDEF_ID);
0225             ppifndef.set_id(BOOST_WAVE_IFNDEF_ID);
0226             ppif.set_id(BOOST_WAVE_IF_ID);
0227             ppelif.set_id(BOOST_WAVE_ELIF_ID);
0228 //             ppelse.set_id(BOOST_WAVE_ELSE_ID);
0229 //             ppendif.set_id(BOOST_WAVE_ENDIF_ID);
0230             ppline.set_id(BOOST_WAVE_LINE_ID);
0231             pperror.set_id(BOOST_WAVE_ERROR_ID);
0232             ppwarning.set_id(BOOST_WAVE_WARNING_ID);
0233             pppragma.set_id(BOOST_WAVE_PRAGMA_ID);
0234             illformed.set_id(BOOST_WAVE_ILLFORMED_ID);
0235             ppsp.set_id(BOOST_WAVE_PPSPACE_ID);
0236             ppqualifiedname.set_id(BOOST_WAVE_PPQUALIFIEDNAME_ID);
0237 #if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
0238             ppregion.set_id(BOOST_WAVE_REGION_ID);
0239             ppendregion.set_id(BOOST_WAVE_ENDREGION_ID);
0240 #endif
0241 
0242 #if BOOST_WAVE_DUMP_PARSE_TREE != 0
0243             self.map_rule_id_to_name.init_rule_id_to_name_map(self);
0244 #endif
0245 
0246         // recognizes preprocessor directives only
0247 
0248         // C++ standard 16.1: A preprocessing directive consists of a sequence
0249         // of preprocessing tokens. The first token in the sequence is #
0250         // preprocessing token that is either the first character in the source
0251         // file (optionally after white space containing no new-line
0252         // characters) or that follows white space containing at least one
0253         // new-line character. The last token in the sequence is the first
0254         // new-line character that follows the first token in the sequence.
0255 
0256             pp_statement
0257                 =   (   plain_define
0258 //                     |   include_file
0259 //                     |   system_include_file
0260                     |   ppif
0261                     |   ppelif
0262                     |   ppifndef
0263                     |   ppifdef
0264                     |   undefine
0265 //                     |   ppelse
0266                     |   macro_include_file
0267                     |   ppline
0268                     |   pppragma
0269                     |   pperror
0270                     |   ppwarning
0271 //                     |   ppendif
0272 #if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
0273                     |   ppregion
0274                     |   ppendregion
0275 #endif
0276                     |   illformed
0277                     )
0278                     >> eol_tokens
0279                        [ store_found_eoltokens_type(self.found_eoltokens) ]
0280 //  In parser debug mode it is useful not to flush the underlying stream
0281 //  to allow its investigation in the debugger and to see the correct
0282 //  output in the printed debug log..
0283 //  Note: this may break the parser, though.
0284 #if !(defined(BOOST_SPIRIT_DEBUG) && \
0285       (BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_CPP_GRAMMAR) \
0286      )
0287                    >>  impl::flush_underlying_parser_p
0288 #endif // !(defined(BOOST_SPIRIT_DEBUG) &&
0289                 ;
0290 
0291 //         // #include ...
0292 //             include_file            // include "..."
0293 //                 =   ch_p(T_PP_QHEADER)
0294 //                     [ store_found_directive_type(self.found_directive) ]
0295 // #if BOOST_WAVE_SUPPORT_INCLUDE_NEXT != 0
0296 //                 |   ch_p(T_PP_QHEADER_NEXT)
0297 //                     [ store_found_directive_type(self.found_directive) ]
0298 // #endif
0299 //                 ;
0300 
0301 //             system_include_file     // include <...>
0302 //                 =   ch_p(T_PP_HHEADER)
0303 //                     [ store_found_directive_type(self.found_directive) ]
0304 // #if BOOST_WAVE_SUPPORT_INCLUDE_NEXT != 0
0305 //                 |   ch_p(T_PP_HHEADER_NEXT)
0306 //                     [ store_found_directive_type(self.found_directive) ]
0307 // #endif
0308 //                 ;
0309 
0310             macro_include_file      // include ...anything else...
0311                 =   no_node_d
0312                     [
0313                         ch_p(T_PP_INCLUDE)
0314                         [ store_found_directive_type(self.found_directive) ]
0315 #if BOOST_WAVE_SUPPORT_INCLUDE_NEXT != 0
0316                     |   ch_p(T_PP_INCLUDE_NEXT)
0317                         [ store_found_directive_type(self.found_directive) ]
0318 #endif
0319                     ]
0320                     >> *(   anychar_p -
0321                             (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
0322                         )
0323                 ;
0324 
0325         // #define FOO foo (with optional parameters)
0326             plain_define
0327                 =   no_node_d
0328                     [
0329                         ch_p(T_PP_DEFINE)
0330                         [ store_found_directive_type(self.found_directive) ]
0331                         >> +ppsp
0332                     ]
0333                     >>  (   ch_p(T_IDENTIFIER)
0334                         |   pattern_p(KeywordTokenType,
0335                                 TokenTypeMask|PPTokenFlag)
0336                         |   pattern_p(OperatorTokenType|AltExtTokenType,
0337                                 ExtTokenTypeMask|PPTokenFlag)   // and, bit_and etc.
0338                         |   pattern_p(BoolLiteralTokenType,
0339                                 TokenTypeMask|PPTokenFlag)  // true/false
0340                         )
0341                     >>  (   (   no_node_d[eps_p(ch_p(T_LEFTPAREN))]
0342                                 >>  macro_parameters
0343                                 >> !macro_definition
0344                             )
0345                         |  !(   no_node_d[+ppsp]
0346                                 >>  macro_definition
0347                             )
0348                         )
0349                 ;
0350 
0351         // parameter list
0352         // normal C++ mode
0353             macro_parameters
0354                 =   confix_p(
0355                         no_node_d[ch_p(T_LEFTPAREN) >> *ppsp],
0356                        !list_p(
0357                             (   ch_p(T_IDENTIFIER)
0358                             |   pattern_p(KeywordTokenType,
0359                                     TokenTypeMask|PPTokenFlag)
0360                             |   pattern_p(OperatorTokenType|AltExtTokenType,
0361                                     ExtTokenTypeMask|PPTokenFlag)   // and, bit_and etc.
0362                             |   pattern_p(BoolLiteralTokenType,
0363                                     TokenTypeMask|PPTokenFlag)  // true/false
0364 #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
0365                             |   ch_p(T_ELLIPSIS)
0366 #endif
0367                             ),
0368                             no_node_d[*ppsp >> ch_p(T_COMMA) >> *ppsp]
0369                         ),
0370                         no_node_d[*ppsp >> ch_p(T_RIGHTPAREN)]
0371                     )
0372                 ;
0373 
0374         // macro body (anything left until eol)
0375             macro_definition
0376                 =   no_node_d[*ppsp]
0377                     >> *(   anychar_p -
0378                             (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
0379                         )
0380                 ;
0381 
0382         // #undef FOO
0383             undefine
0384                 =   no_node_d
0385                     [
0386                         ch_p(T_PP_UNDEF)
0387                         [ store_found_directive_type(self.found_directive) ]
0388                         >> +ppsp
0389                     ]
0390                     >>  (   ch_p(T_IDENTIFIER)
0391                         |   pattern_p(KeywordTokenType,
0392                                 TokenTypeMask|PPTokenFlag)
0393                         |   pattern_p(OperatorTokenType|AltExtTokenType,
0394                                 ExtTokenTypeMask|PPTokenFlag)   // and, bit_and etc.
0395                         |   pattern_p(BoolLiteralTokenType,
0396                                 TokenTypeMask|PPTokenFlag)  // true/false
0397                         )
0398                 ;
0399 
0400         // #ifdef et.al.
0401             ppifdef
0402                 =   no_node_d
0403                     [
0404                         ch_p(T_PP_IFDEF)
0405                         [ store_found_directive_type(self.found_directive) ]
0406                         >> +ppsp
0407                     ]
0408                     >>  ppqualifiedname
0409                 ;
0410 
0411             ppifndef
0412                 =   no_node_d
0413                     [
0414                         ch_p(T_PP_IFNDEF)
0415                         [ store_found_directive_type(self.found_directive) ]
0416                         >> +ppsp
0417                     ]
0418                     >>  ppqualifiedname
0419                 ;
0420 
0421             ppif
0422                 =   no_node_d
0423                     [
0424                         ch_p(T_PP_IF)
0425                         [ store_found_directive_type(self.found_directive) ]
0426 //                        >> *ppsp
0427                     ]
0428                     >> +(   anychar_p -
0429                             (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
0430                         )
0431                 ;
0432 
0433 //             ppelse
0434 //                 =   no_node_d
0435 //                     [
0436 //                         ch_p(T_PP_ELSE)
0437 //                         [ store_found_directive_type(self.found_directive) ]
0438 //                     ]
0439 //                 ;
0440 
0441             ppelif
0442                 =   no_node_d
0443                     [
0444                         ch_p(T_PP_ELIF)
0445                         [ store_found_directive_type(self.found_directive) ]
0446 //                        >> *ppsp
0447                     ]
0448                     >> +(   anychar_p -
0449                             (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
0450                         )
0451                 ;
0452 
0453 //             ppendif
0454 //                 =   no_node_d
0455 //                     [
0456 //                         ch_p(T_PP_ENDIF)
0457 //                         [ store_found_directive_type(self.found_directive) ]
0458 //                     ]
0459 //                 ;
0460 
0461         // #line ...
0462             ppline
0463                 =   no_node_d
0464                     [
0465                         ch_p(T_PP_LINE)
0466                         [ store_found_directive_type(self.found_directive) ]
0467                         >> *ppsp
0468                     ]
0469                     >> +(   anychar_p -
0470                             (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
0471                         )
0472                 ;
0473 
0474 #if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
0475         // #region ...
0476             ppregion
0477                 =   no_node_d
0478                     [
0479                         ch_p(T_MSEXT_PP_REGION)
0480                         [ store_found_directive_type(self.found_directive) ]
0481                         >> +ppsp
0482                     ]
0483                     >>  ppqualifiedname
0484                 ;
0485 
0486         // #endregion
0487             ppendregion
0488                 =   no_node_d
0489                     [
0490                         ch_p(T_MSEXT_PP_ENDREGION)
0491                         [ store_found_directive_type(self.found_directive) ]
0492                     ]
0493                 ;
0494 #endif
0495 
0496         // # something else (ill formed preprocessor directive)
0497             illformed           // for error reporting
0498                 =   no_node_d
0499                     [
0500                         pattern_p(T_POUND, MainTokenMask)
0501                         >> *ppsp
0502                     ]
0503                     >>  (   anychar_p -
0504                             (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
0505                         )
0506                     >>  no_node_d
0507                         [
0508                            *(   anychar_p -
0509                                 (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
0510                             )
0511                         ]
0512                 ;
0513 
0514         // #error
0515             pperror
0516                 =   no_node_d
0517                     [
0518                         ch_p(T_PP_ERROR)
0519                         [ store_found_directive_type(self.found_directive) ]
0520                         >> *ppsp
0521                     ]
0522                     >> *(   anychar_p -
0523                             (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
0524                         )
0525                 ;
0526 
0527         // #warning
0528             ppwarning
0529                 =   no_node_d
0530                     [
0531                         ch_p(T_PP_WARNING)
0532                         [ store_found_directive_type(self.found_directive) ]
0533                         >> *ppsp
0534                     ]
0535                     >> *(   anychar_p -
0536                             (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
0537                         )
0538                 ;
0539 
0540         // #pragma ...
0541             pppragma
0542                 =   no_node_d
0543                     [
0544                         ch_p(T_PP_PRAGMA)
0545                         [ store_found_directive_type(self.found_directive) ]
0546                     ]
0547                     >> *(   anychar_p -
0548                             (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
0549                         )
0550                 ;
0551 
0552             ppqualifiedname
0553                 =   no_node_d[*ppsp]
0554                     >>  (   ch_p(T_IDENTIFIER)
0555                         |   pattern_p(KeywordTokenType,
0556                                 TokenTypeMask|PPTokenFlag)
0557                         |   pattern_p(OperatorTokenType|AltExtTokenType,
0558                                 ExtTokenTypeMask|PPTokenFlag)   // and, bit_and etc.
0559                         |   pattern_p(BoolLiteralTokenType,
0560                                 TokenTypeMask|PPTokenFlag)  // true/false
0561                         )
0562                 ;
0563 
0564         // auxiliary helper rules
0565             ppsp     // valid space in a line with a preprocessor directive
0566                 =   ch_p(T_SPACE) | ch_p(T_CCOMMENT)
0567                 ;
0568 
0569         // end of line tokens
0570             eol_tokens
0571                 =   no_node_d
0572                     [
0573                        *(   ch_p(T_SPACE)
0574                         |   ch_p(T_CCOMMENT)
0575                         )
0576                     >>  (   ch_p(T_NEWLINE)
0577                         |   ch_p(T_CPPCOMMENT)
0578                         |   ch_p(T_EOF)
0579                             [ store_found_eof_type(self.found_eof) ]
0580                         )
0581                     ]
0582                 ;
0583 
0584             BOOST_SPIRIT_DEBUG_TRACE_RULE(pp_statement, TRACE_CPP_GRAMMAR);
0585 //             BOOST_SPIRIT_DEBUG_TRACE_RULE(include_file, TRACE_CPP_GRAMMAR);
0586 //             BOOST_SPIRIT_DEBUG_TRACE_RULE(system_include_file, TRACE_CPP_GRAMMAR);
0587             BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_include_file, TRACE_CPP_GRAMMAR);
0588             BOOST_SPIRIT_DEBUG_TRACE_RULE(plain_define, TRACE_CPP_GRAMMAR);
0589             BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_definition, TRACE_CPP_GRAMMAR);
0590             BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_parameters, TRACE_CPP_GRAMMAR);
0591             BOOST_SPIRIT_DEBUG_TRACE_RULE(undefine, TRACE_CPP_GRAMMAR);
0592             BOOST_SPIRIT_DEBUG_TRACE_RULE(ppifdef, TRACE_CPP_GRAMMAR);
0593             BOOST_SPIRIT_DEBUG_TRACE_RULE(ppifndef, TRACE_CPP_GRAMMAR);
0594             BOOST_SPIRIT_DEBUG_TRACE_RULE(ppif, TRACE_CPP_GRAMMAR);
0595 //             BOOST_SPIRIT_DEBUG_TRACE_RULE(ppelse, TRACE_CPP_GRAMMAR);
0596              BOOST_SPIRIT_DEBUG_TRACE_RULE(ppelif, TRACE_CPP_GRAMMAR);
0597 //            BOOST_SPIRIT_DEBUG_TRACE_RULE(ppendif, TRACE_CPP_GRAMMAR);
0598             BOOST_SPIRIT_DEBUG_TRACE_RULE(ppline, TRACE_CPP_GRAMMAR);
0599             BOOST_SPIRIT_DEBUG_TRACE_RULE(pperror, TRACE_CPP_GRAMMAR);
0600             BOOST_SPIRIT_DEBUG_TRACE_RULE(ppwarning, TRACE_CPP_GRAMMAR);
0601             BOOST_SPIRIT_DEBUG_TRACE_RULE(illformed, TRACE_CPP_GRAMMAR);
0602             BOOST_SPIRIT_DEBUG_TRACE_RULE(ppsp, TRACE_CPP_GRAMMAR);
0603             BOOST_SPIRIT_DEBUG_TRACE_RULE(ppqualifiedname, TRACE_CPP_GRAMMAR);
0604 #if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
0605             BOOST_SPIRIT_DEBUG_TRACE_RULE(ppregion, TRACE_CPP_GRAMMAR);
0606             BOOST_SPIRIT_DEBUG_TRACE_RULE(ppendregion, TRACE_CPP_GRAMMAR);
0607 #endif
0608         }
0609 
0610         // start rule of this grammar
0611         rule_type const& start() const
0612         { return pp_statement; }
0613     };
0614 
0615     bool &found_eof;
0616     TokenT &found_directive;
0617     ContainerT &found_eoltokens;
0618 
0619     cpp_grammar(bool &found_eof_, TokenT &found_directive_,
0620             ContainerT &found_eoltokens_)
0621     :   found_eof(found_eof_),
0622         found_directive(found_directive_),
0623         found_eoltokens(found_eoltokens_)
0624     {
0625         BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this, "cpp_grammar",
0626             TRACE_CPP_GRAMMAR);
0627     }
0628 
0629 #if BOOST_WAVE_DUMP_PARSE_TREE != 0
0630     // helper function and data to get readable names of the rules known to us
0631     struct map_ruleid_to_name :
0632         public std::map<boost::spirit::classic::parser_id, std::string>
0633     {
0634         typedef std::map<boost::spirit::classic::parser_id, std::string> base_type;
0635 
0636         void init_rule_id_to_name_map(cpp_grammar const &self)
0637         {
0638             struct {
0639                 int parser_id;
0640                 char const *rule_name;
0641             }
0642             init_ruleid_name_map[] = {
0643                 { BOOST_WAVE_PP_STATEMENT_ID, "pp_statement" },
0644 //                 { BOOST_WAVE_INCLUDE_FILE_ID, "include_file" },
0645 //                 { BOOST_WAVE_SYSINCLUDE_FILE_ID, "system_include_file" },
0646                 { BOOST_WAVE_MACROINCLUDE_FILE_ID, "macro_include_file" },
0647                 { BOOST_WAVE_PLAIN_DEFINE_ID, "plain_define" },
0648                 { BOOST_WAVE_MACRO_PARAMETERS_ID, "macro_parameters" },
0649                 { BOOST_WAVE_MACRO_DEFINITION_ID, "macro_definition" },
0650                 { BOOST_WAVE_UNDEFINE_ID, "undefine" },
0651                 { BOOST_WAVE_IFDEF_ID, "ppifdef" },
0652                 { BOOST_WAVE_IFNDEF_ID, "ppifndef" },
0653                 { BOOST_WAVE_IF_ID, "ppif" },
0654                 { BOOST_WAVE_ELIF_ID, "ppelif" },
0655 //                 { BOOST_WAVE_ELSE_ID, "ppelse" },
0656 //                 { BOOST_WAVE_ENDIF_ID, "ppendif" },
0657                 { BOOST_WAVE_LINE_ID, "ppline" },
0658                 { BOOST_WAVE_ERROR_ID, "pperror" },
0659                 { BOOST_WAVE_WARNING_ID, "ppwarning" },
0660                 { BOOST_WAVE_PRAGMA_ID, "pppragma" },
0661                 { BOOST_WAVE_ILLFORMED_ID, "illformed" },
0662                 { BOOST_WAVE_PPSPACE_ID, "ppspace" },
0663                 { BOOST_WAVE_PPQUALIFIEDNAME_ID, "ppqualifiedname" },
0664 #if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
0665                 { BOOST_WAVE_REGION_ID, "ppregion" },
0666                 { BOOST_WAVE_ENDREGION_ID, "ppendregion" },
0667 #endif
0668                 { 0 }
0669             };
0670 
0671             // initialize parser_id to rule_name map
0672             for (int i = 0; 0 != init_ruleid_name_map[i].parser_id; ++i)
0673                 base_type::insert(base_type::value_type(
0674                     boost::spirit::classic::parser_id(init_ruleid_name_map[i].parser_id),
0675                     std::string(init_ruleid_name_map[i].rule_name))
0676                 );
0677         }
0678     };
0679     mutable map_ruleid_to_name map_rule_id_to_name;
0680 #endif // WAVE_DUMP_PARSE_TREE != 0
0681 };
0682 
0683 ///////////////////////////////////////////////////////////////////////////////
0684 #undef TRACE_CPP_GRAMMAR
0685 
0686 ///////////////////////////////////////////////////////////////////////////////
0687 //
0688 //  Special parse function generating a parse tree using a given node_factory.
0689 //
0690 ///////////////////////////////////////////////////////////////////////////////
0691 template <typename NodeFactoryT, typename IteratorT, typename ParserT>
0692 inline boost::spirit::classic::tree_parse_info<IteratorT, NodeFactoryT>
0693 parsetree_parse(IteratorT const& first_, IteratorT const& last,
0694     boost::spirit::classic::parser<ParserT> const& p)
0695 {
0696     using namespace boost::spirit::classic;
0697 
0698     typedef pt_match_policy<IteratorT, NodeFactoryT> pt_match_policy_type;
0699     typedef scanner_policies<iteration_policy, pt_match_policy_type>
0700         scanner_policies_type;
0701     typedef scanner<IteratorT, scanner_policies_type> scanner_type;
0702 
0703     scanner_policies_type policies;
0704     IteratorT first = first_;
0705     scanner_type scan(first, last, policies);
0706     tree_match<IteratorT, NodeFactoryT> hit = p.derived().parse(scan);
0707     return tree_parse_info<IteratorT, NodeFactoryT>(
0708         first, hit, hit && (first == last), hit.length(), hit.trees);
0709 }
0710 
0711 ///////////////////////////////////////////////////////////////////////////////
0712 //
0713 //  The following parse function is defined here, to allow the separation of
0714 //  the compilation of the cpp_grammar from the function using it.
0715 //
0716 ///////////////////////////////////////////////////////////////////////////////
0717 
0718 #if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
0719 #define BOOST_WAVE_GRAMMAR_GEN_INLINE
0720 #else
0721 #define BOOST_WAVE_GRAMMAR_GEN_INLINE inline
0722 #endif
0723 
0724 template <typename LexIteratorT, typename TokenContainerT>
0725 BOOST_WAVE_GRAMMAR_GEN_INLINE
0726 boost::spirit::classic::tree_parse_info<
0727     LexIteratorT,
0728     typename cpp_grammar_gen<LexIteratorT, TokenContainerT>::node_factory_type
0729 >
0730 cpp_grammar_gen<LexIteratorT, TokenContainerT>::parse_cpp_grammar (
0731     LexIteratorT const &first, LexIteratorT const &last,
0732     position_type const &act_pos, bool &found_eof,
0733     token_type &found_directive, token_container_type &found_eoltokens)
0734 {
0735     using namespace boost::spirit::classic;
0736     using namespace boost::wave;
0737 
0738     cpp_grammar<token_type, TokenContainerT> g(found_eof, found_directive, found_eoltokens);
0739     tree_parse_info<LexIteratorT, node_factory_type> hit =
0740         parsetree_parse<node_factory_type>(first, last, g);
0741 
0742 #if BOOST_WAVE_DUMP_PARSE_TREE != 0
0743     if (hit.match) {
0744         tree_to_xml (BOOST_WAVE_DUMP_PARSE_TREE_OUT, hit.trees, "",
0745             g.map_rule_id_to_name, &token_type::get_token_id,
0746             &token_type::get_token_value);
0747     }
0748 #endif
0749 
0750     return hit;
0751 }
0752 
0753 #undef BOOST_WAVE_GRAMMAR_GEN_INLINE
0754 
0755 ///////////////////////////////////////////////////////////////////////////////
0756 }   // namespace grammars
0757 }   // namespace wave
0758 }   // namespace boost
0759 
0760 // the suffix header occurs after all of the code
0761 #ifdef BOOST_HAS_ABI_HEADERS
0762 #include BOOST_ABI_SUFFIX
0763 #endif
0764 
0765 #endif // !defined(BOOST_CPP_GRAMMAR_HPP_FEAEBC2E_2734_428B_A7CA_85E5A415E23E_INCLUDED)