diff DEPENDENCIES/generic/include/boost/wave/grammars/cpp_grammar.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DEPENDENCIES/generic/include/boost/wave/grammars/cpp_grammar.hpp	Tue Aug 05 11:11:38 2014 +0100
@@ -0,0 +1,765 @@
+/*=============================================================================
+    Boost.Wave: A Standard compliant C++ preprocessor library
+
+    http://www.boost.org/
+
+    Copyright (c) 2001-2012 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_GRAMMAR_HPP_FEAEBC2E_2734_428B_A7CA_85E5A415E23E_INCLUDED)
+#define CPP_GRAMMAR_HPP_FEAEBC2E_2734_428B_A7CA_85E5A415E23E_INCLUDED
+
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_parse_tree.hpp>
+#include <boost/spirit/include/classic_parse_tree_utils.hpp>
+#include <boost/spirit/include/classic_confix.hpp>
+#include <boost/spirit/include/classic_lists.hpp>
+
+#include <boost/wave/wave_config.hpp>
+#include <boost/pool/pool_alloc.hpp>
+
+#if BOOST_WAVE_DUMP_PARSE_TREE != 0
+#include <map>
+#include <boost/spirit/include/classic_tree_to_xml.hpp>
+#endif
+
+#include <boost/wave/token_ids.hpp>
+#include <boost/wave/grammars/cpp_grammar_gen.hpp>
+#include <boost/wave/util/pattern_parser.hpp>
+
+#include <boost/wave/cpp_exceptions.hpp>
+
+// this must occur after all of the includes and before any code appears
+#ifdef BOOST_HAS_ABI_HEADERS
+#include BOOST_ABI_PREFIX
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost {
+namespace wave { 
+namespace grammars {
+
+namespace impl {
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  store_found_eof
+//
+//      The store_found_eof functor sets a given flag if the T_EOF token was 
+//      found during the parsing process
+//
+///////////////////////////////////////////////////////////////////////////////
+
+    struct store_found_eof {
+
+        store_found_eof(bool &found_eof_) : found_eof(found_eof_) {}
+        
+        template <typename TokenT>
+        void operator()(TokenT const &/*token*/) const
+        {
+            found_eof = true;
+        }
+        
+        bool &found_eof;
+    };
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  store_found_directive
+//
+//      The store_found_directive functor stores the token_id of the recognized
+//      pp directive
+//
+///////////////////////////////////////////////////////////////////////////////
+
+    template <typename TokenT>
+    struct store_found_directive {
+
+        store_found_directive(TokenT &found_directive_) 
+        :   found_directive(found_directive_) {}
+        
+        void operator()(TokenT const &token) const
+        {
+            found_directive = token;
+        }
+        
+        TokenT &found_directive;
+    };
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  store_found_eoltokens
+//
+//      The store_found_eoltokens functor stores the token sequence of the 
+//      line ending for a particular pp directive
+//
+///////////////////////////////////////////////////////////////////////////////
+
+    template <typename ContainerT>
+    struct store_found_eoltokens {
+
+        store_found_eoltokens(ContainerT &found_eoltokens_) 
+        :   found_eoltokens(found_eoltokens_) {}
+        
+        template <typename IteratorT>
+        void operator()(IteratorT const &first, IteratorT const& last) const
+        {
+            std::copy(first, last, 
+                std::inserter(found_eoltokens, found_eoltokens.end()));
+        }
+        
+        ContainerT &found_eoltokens;
+    };
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  flush_underlying_parser
+//
+//      The flush_underlying_parser flushes the underlying
+//      multi_pass_iterator during the normal parsing process. This is
+//      used at certain points during the parsing process, when it is
+//      clear, that no backtracking is needed anymore and the input
+//      gathered so far may be discarded.
+//
+///////////////////////////////////////////////////////////////////////////////
+    struct flush_underlying_parser
+    :   public boost::spirit::classic::parser<flush_underlying_parser>
+    {
+        typedef flush_underlying_parser this_t;
+
+        template <typename ScannerT>
+        typename boost::spirit::classic::parser_result<this_t, ScannerT>::type
+        parse(ScannerT const& scan) const
+        {
+            scan.first.clear_queue();
+            return scan.empty_match();  
+        }
+    };
+
+    flush_underlying_parser const 
+        flush_underlying_parser_p = flush_underlying_parser();
+
+}   // anonymous namespace
+
+///////////////////////////////////////////////////////////////////////////////
+//  define, whether the rule's should generate some debug output
+#define TRACE_CPP_GRAMMAR \
+    bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_CPP_GRAMMAR) \
+    /**/
+
+///////////////////////////////////////////////////////////////////////////////
+// Encapsulation of the C++ preprocessor grammar.
+template <typename TokenT, typename ContainerT>
+struct cpp_grammar : 
+    public boost::spirit::classic::grammar<cpp_grammar<TokenT, ContainerT> >
+{
+    typedef typename TokenT::position_type  position_type;
+    typedef cpp_grammar<TokenT, ContainerT> grammar_type;
+    typedef impl::store_found_eof           store_found_eof_type;
+    typedef impl::store_found_directive<TokenT>     store_found_directive_type;
+    typedef impl::store_found_eoltokens<ContainerT> store_found_eoltokens_type;
+    
+    template <typename ScannerT>
+    struct definition
+    {
+    // non-parse_tree generating rule type
+        typedef typename ScannerT::iteration_policy_t iteration_policy_t;
+        typedef boost::spirit::classic::match_policy match_policy_t;
+        typedef typename ScannerT::action_policy_t action_policy_t;
+        typedef 
+            boost::spirit::classic::scanner_policies<
+                iteration_policy_t, match_policy_t, action_policy_t> 
+            policies_t;
+        typedef 
+            boost::spirit::classic::scanner<typename ScannerT::iterator_t, policies_t> 
+            non_tree_scanner_t;
+        typedef 
+            boost::spirit::classic::rule<
+                non_tree_scanner_t, boost::spirit::classic::dynamic_parser_tag> 
+            no_tree_rule_type;
+
+    // 'normal' (parse_tree generating) rule type
+        typedef 
+            boost::spirit::classic::rule<
+                ScannerT, boost::spirit::classic::dynamic_parser_tag> 
+            rule_type;
+
+        rule_type pp_statement, macro_include_file;
+//         rule_type include_file, system_include_file;
+        rule_type plain_define, macro_definition, macro_parameters;
+        rule_type undefine;
+        rule_type ppifdef, ppifndef, ppif, ppelif;
+//         rule_type ppelse, ppendif;
+        rule_type ppline; 
+        rule_type pperror;
+        rule_type ppwarning;
+        rule_type pppragma;
+        rule_type illformed;
+        rule_type ppqualifiedname;
+        rule_type eol_tokens;
+        no_tree_rule_type ppsp;
+#if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
+        rule_type ppregion;
+        rule_type ppendregion;
+#endif
+
+        definition(cpp_grammar const &self) 
+        {
+        // import the spirit and cpplexer namespaces here
+            using namespace boost::spirit::classic;
+            using namespace boost::wave;
+            using namespace boost::wave::util;
+
+        // set the rule id's for later use
+            pp_statement.set_id(BOOST_WAVE_PP_STATEMENT_ID);
+//             include_file.set_id(BOOST_WAVE_INCLUDE_FILE_ID);
+//             system_include_file.set_id(BOOST_WAVE_SYSINCLUDE_FILE_ID);
+            macro_include_file.set_id(BOOST_WAVE_MACROINCLUDE_FILE_ID);
+            plain_define.set_id(BOOST_WAVE_PLAIN_DEFINE_ID);
+            macro_parameters.set_id(BOOST_WAVE_MACRO_PARAMETERS_ID);
+            macro_definition.set_id(BOOST_WAVE_MACRO_DEFINITION_ID);
+            undefine.set_id(BOOST_WAVE_UNDEFINE_ID);
+            ppifdef.set_id(BOOST_WAVE_IFDEF_ID);
+            ppifndef.set_id(BOOST_WAVE_IFNDEF_ID);
+            ppif.set_id(BOOST_WAVE_IF_ID);
+            ppelif.set_id(BOOST_WAVE_ELIF_ID);
+//             ppelse.set_id(BOOST_WAVE_ELSE_ID);
+//             ppendif.set_id(BOOST_WAVE_ENDIF_ID);
+            ppline.set_id(BOOST_WAVE_LINE_ID);
+            pperror.set_id(BOOST_WAVE_ERROR_ID);
+            ppwarning.set_id(BOOST_WAVE_WARNING_ID);
+            pppragma.set_id(BOOST_WAVE_PRAGMA_ID);
+            illformed.set_id(BOOST_WAVE_ILLFORMED_ID);
+            ppsp.set_id(BOOST_WAVE_PPSPACE_ID);
+            ppqualifiedname.set_id(BOOST_WAVE_PPQUALIFIEDNAME_ID);
+#if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
+            ppregion.set_id(BOOST_WAVE_REGION_ID);
+            ppendregion.set_id(BOOST_WAVE_ENDREGION_ID);
+#endif
+
+#if BOOST_WAVE_DUMP_PARSE_TREE != 0
+            self.map_rule_id_to_name.init_rule_id_to_name_map(self);
+#endif 
+
+        // recognizes preprocessor directives only
+
+        // C++ standard 16.1: A preprocessing directive consists of a sequence 
+        // of preprocessing tokens. The first token in the sequence is # 
+        // preprocessing token that is either the first character in the source 
+        // file (optionally after white space containing no new-line 
+        // characters) or that follows white space containing at least one 
+        // new-line character. The last token in the sequence is the first 
+        // new-line character that follows the first token in the sequence.
+
+            pp_statement
+                =   (   plain_define
+//                     |   include_file
+//                     |   system_include_file
+                    |   ppif
+                    |   ppelif
+                    |   ppifndef
+                    |   ppifdef
+                    |   undefine
+//                     |   ppelse
+                    |   macro_include_file
+                    |   ppline
+                    |   pppragma
+                    |   pperror
+                    |   ppwarning
+//                     |   ppendif
+#if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
+                    |   ppregion
+                    |   ppendregion
+#endif
+                    |   illformed
+                    )
+                    >> eol_tokens
+                       [ store_found_eoltokens_type(self.found_eoltokens) ]
+//  In parser debug mode it is useful not to flush the underlying stream
+//  to allow its investigation in the debugger and to see the correct
+//  output in the printed debug log..
+//  Note: this may break the parser, though.
+#if !(defined(BOOST_SPIRIT_DEBUG) && \
+      (BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_CPP_GRAMMAR) \
+     )
+                   >>  impl::flush_underlying_parser_p
+#endif // !(defined(BOOST_SPIRIT_DEBUG) &&
+                ;
+
+//         // #include ...
+//             include_file            // include "..."
+//                 =   ch_p(T_PP_QHEADER) 
+//                     [ store_found_directive_type(self.found_directive) ]
+// #if BOOST_WAVE_SUPPORT_INCLUDE_NEXT != 0
+//                 |   ch_p(T_PP_QHEADER_NEXT)
+//                     [ store_found_directive_type(self.found_directive) ]
+// #endif 
+//                 ;
+
+//             system_include_file     // include <...>
+//                 =   ch_p(T_PP_HHEADER) 
+//                     [ store_found_directive_type(self.found_directive) ]
+// #if BOOST_WAVE_SUPPORT_INCLUDE_NEXT != 0
+//                 |   ch_p(T_PP_HHEADER_NEXT)
+//                     [ store_found_directive_type(self.found_directive) ]
+// #endif 
+//                 ;
+
+            macro_include_file      // include ...anything else...
+                =   no_node_d
+                    [
+                        ch_p(T_PP_INCLUDE)
+                        [ store_found_directive_type(self.found_directive) ]
+#if BOOST_WAVE_SUPPORT_INCLUDE_NEXT != 0
+                    |   ch_p(T_PP_INCLUDE_NEXT)
+                        [ store_found_directive_type(self.found_directive) ]
+#endif
+                    ]
+                    >> *(   anychar_p -
+                            (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF)) 
+                        )
+                ;
+
+        // #define FOO foo (with optional parameters)
+            plain_define
+                =   no_node_d
+                    [
+                        ch_p(T_PP_DEFINE) 
+                        [ store_found_directive_type(self.found_directive) ]
+                        >> +ppsp
+                    ]
+                    >>  (   ch_p(T_IDENTIFIER) 
+                        |   pattern_p(KeywordTokenType, 
+                                TokenTypeMask|PPTokenFlag)
+                        |   pattern_p(OperatorTokenType|AltExtTokenType, 
+                                ExtTokenTypeMask|PPTokenFlag)   // and, bit_and etc.
+                        |   pattern_p(BoolLiteralTokenType, 
+                                TokenTypeMask|PPTokenFlag)  // true/false
+                        )
+                    >>  (   (   no_node_d[eps_p(ch_p(T_LEFTPAREN))]
+                                >>  macro_parameters
+                                >> !macro_definition
+                            )
+                        |  !(   no_node_d[+ppsp] 
+                                >>  macro_definition
+                            )
+                        )
+                ;
+
+        // parameter list
+        // normal C++ mode
+            macro_parameters
+                =   confix_p(
+                        no_node_d[ch_p(T_LEFTPAREN) >> *ppsp],
+                       !list_p(
+                            (   ch_p(T_IDENTIFIER) 
+                            |   pattern_p(KeywordTokenType, 
+                                    TokenTypeMask|PPTokenFlag)
+                            |   pattern_p(OperatorTokenType|AltExtTokenType, 
+                                    ExtTokenTypeMask|PPTokenFlag)   // and, bit_and etc.
+                            |   pattern_p(BoolLiteralTokenType, 
+                                    TokenTypeMask|PPTokenFlag)  // true/false
+#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
+                            |   ch_p(T_ELLIPSIS)
+#endif
+                            ), 
+                            no_node_d[*ppsp >> ch_p(T_COMMA) >> *ppsp]
+                        ),
+                        no_node_d[*ppsp >> ch_p(T_RIGHTPAREN)]
+                    )
+                ;
+            
+        // macro body (anything left until eol)
+            macro_definition
+                =   no_node_d[*ppsp]
+                    >> *(   anychar_p -
+                            (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF)) 
+                        )
+                ;
+
+        // #undef FOO 
+            undefine
+                =   no_node_d
+                    [
+                        ch_p(T_PP_UNDEF) 
+                        [ store_found_directive_type(self.found_directive) ]
+                        >> +ppsp
+                    ]
+                    >>  (   ch_p(T_IDENTIFIER) 
+                        |   pattern_p(KeywordTokenType, 
+                                TokenTypeMask|PPTokenFlag)
+                        |   pattern_p(OperatorTokenType|AltExtTokenType, 
+                                ExtTokenTypeMask|PPTokenFlag)   // and, bit_and etc.
+                        |   pattern_p(BoolLiteralTokenType, 
+                                TokenTypeMask|PPTokenFlag)  // true/false
+                        )
+                ;
+
+        // #ifdef et.al.
+            ppifdef
+                =   no_node_d
+                    [
+                        ch_p(T_PP_IFDEF) 
+                        [ store_found_directive_type(self.found_directive) ]
+                        >> +ppsp
+                    ]
+                    >>  ppqualifiedname
+                ;
+
+            ppifndef
+                =   no_node_d
+                    [
+                        ch_p(T_PP_IFNDEF) 
+                        [ store_found_directive_type(self.found_directive) ]
+                        >> +ppsp
+                    ]
+                    >>  ppqualifiedname
+                ;
+
+            ppif
+                =   no_node_d
+                    [
+                        ch_p(T_PP_IF) 
+                        [ store_found_directive_type(self.found_directive) ]
+//                        >> *ppsp
+                    ]
+                    >> +(   anychar_p -
+                            (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF)) 
+                        )
+                ;
+
+//             ppelse
+//                 =   no_node_d
+//                     [
+//                         ch_p(T_PP_ELSE)
+//                         [ store_found_directive_type(self.found_directive) ]
+//                     ]
+//                 ;
+
+            ppelif
+                =   no_node_d
+                    [
+                        ch_p(T_PP_ELIF) 
+                        [ store_found_directive_type(self.found_directive) ]
+//                        >> *ppsp
+                    ]
+                    >> +(   anychar_p -
+                            (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF)) 
+                        )
+                ;
+
+//             ppendif
+//                 =   no_node_d
+//                     [
+//                         ch_p(T_PP_ENDIF)
+//                         [ store_found_directive_type(self.found_directive) ]
+//                     ]
+//                 ;
+
+        // #line ...
+            ppline 
+                =   no_node_d
+                    [
+                        ch_p(T_PP_LINE) 
+                        [ store_found_directive_type(self.found_directive) ]
+                        >> *ppsp
+                    ]
+                    >> +(   anychar_p -
+                            (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF)) 
+                        )
+                ;
+                
+#if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
+        // #region ...
+            ppregion
+                =   no_node_d
+                    [
+                        ch_p(T_MSEXT_PP_REGION) 
+                        [ store_found_directive_type(self.found_directive) ]
+                        >> +ppsp
+                    ]
+                    >>  ppqualifiedname
+                ;
+
+        // #endregion
+            ppendregion
+                =   no_node_d
+                    [
+                        ch_p(T_MSEXT_PP_ENDREGION) 
+                        [ store_found_directive_type(self.found_directive) ]
+                    ]
+                ;
+#endif
+
+        // # something else (ill formed preprocessor directive)
+            illformed           // for error reporting
+                =   no_node_d
+                    [
+                        pattern_p(T_POUND, MainTokenMask) 
+                        >> *ppsp
+                    ]
+                    >>  (   anychar_p -
+                            (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF)) 
+                        )
+                    >>  no_node_d
+                        [
+                           *(   anychar_p -
+                                (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF)) 
+                            )
+                        ]
+                ;
+
+        // #error
+            pperror
+                =   no_node_d
+                    [
+                        ch_p(T_PP_ERROR) 
+                        [ store_found_directive_type(self.found_directive) ]
+                        >> *ppsp
+                    ]
+                    >> *(   anychar_p -
+                            (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF)) 
+                        )
+                ;
+
+        // #warning
+            ppwarning
+                =   no_node_d
+                    [
+                        ch_p(T_PP_WARNING) 
+                        [ store_found_directive_type(self.found_directive) ]
+                        >> *ppsp
+                    ]
+                    >> *(   anychar_p -
+                            (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF)) 
+                        )
+                ;
+
+        // #pragma ...
+            pppragma
+                =   no_node_d
+                    [
+                        ch_p(T_PP_PRAGMA)
+                        [ store_found_directive_type(self.found_directive) ]
+                    ] 
+                    >> *(   anychar_p -
+                            (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF)) 
+                        )
+                ;
+
+            ppqualifiedname
+                =   no_node_d[*ppsp]
+                    >>  (   ch_p(T_IDENTIFIER) 
+                        |   pattern_p(KeywordTokenType, 
+                                TokenTypeMask|PPTokenFlag)
+                        |   pattern_p(OperatorTokenType|AltExtTokenType, 
+                                ExtTokenTypeMask|PPTokenFlag)   // and, bit_and etc.
+                        |   pattern_p(BoolLiteralTokenType, 
+                                TokenTypeMask|PPTokenFlag)  // true/false
+                        ) 
+                ;
+
+        // auxiliary helper rules
+            ppsp     // valid space in a line with a preprocessor directive
+                =   ch_p(T_SPACE) | ch_p(T_CCOMMENT)
+                ;
+
+        // end of line tokens
+            eol_tokens 
+                =   no_node_d
+                    [
+                       *(   ch_p(T_SPACE) 
+                        |   ch_p(T_CCOMMENT)
+                        )
+                    >>  (   ch_p(T_NEWLINE)
+                        |   ch_p(T_CPPCOMMENT)
+                        |   ch_p(T_EOF)
+                            [ store_found_eof_type(self.found_eof) ]
+                        )
+                    ]
+                ;
+
+            BOOST_SPIRIT_DEBUG_TRACE_RULE(pp_statement, TRACE_CPP_GRAMMAR);
+//             BOOST_SPIRIT_DEBUG_TRACE_RULE(include_file, TRACE_CPP_GRAMMAR);
+//             BOOST_SPIRIT_DEBUG_TRACE_RULE(system_include_file, TRACE_CPP_GRAMMAR);
+            BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_include_file, TRACE_CPP_GRAMMAR);
+            BOOST_SPIRIT_DEBUG_TRACE_RULE(plain_define, TRACE_CPP_GRAMMAR);
+            BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_definition, TRACE_CPP_GRAMMAR);
+            BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_parameters, TRACE_CPP_GRAMMAR);
+            BOOST_SPIRIT_DEBUG_TRACE_RULE(undefine, TRACE_CPP_GRAMMAR);
+            BOOST_SPIRIT_DEBUG_TRACE_RULE(ppifdef, TRACE_CPP_GRAMMAR);
+            BOOST_SPIRIT_DEBUG_TRACE_RULE(ppifndef, TRACE_CPP_GRAMMAR);
+            BOOST_SPIRIT_DEBUG_TRACE_RULE(ppif, TRACE_CPP_GRAMMAR);
+//             BOOST_SPIRIT_DEBUG_TRACE_RULE(ppelse, TRACE_CPP_GRAMMAR);
+//             BOOST_SPIRIT_DEBUG_TRACE_RULE(ppelif, TRACE_CPP_GRAMMAR);
+            BOOST_SPIRIT_DEBUG_TRACE_RULE(ppendif, TRACE_CPP_GRAMMAR);
+            BOOST_SPIRIT_DEBUG_TRACE_RULE(ppline, TRACE_CPP_GRAMMAR);
+            BOOST_SPIRIT_DEBUG_TRACE_RULE(pperror, TRACE_CPP_GRAMMAR);
+            BOOST_SPIRIT_DEBUG_TRACE_RULE(ppwarning, TRACE_CPP_GRAMMAR);
+            BOOST_SPIRIT_DEBUG_TRACE_RULE(illformed, TRACE_CPP_GRAMMAR);
+            BOOST_SPIRIT_DEBUG_TRACE_RULE(ppsp, TRACE_CPP_GRAMMAR);
+            BOOST_SPIRIT_DEBUG_TRACE_RULE(ppqualifiedname, TRACE_CPP_GRAMMAR);
+#if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
+            BOOST_SPIRIT_DEBUG_TRACE_RULE(ppregion, TRACE_CPP_GRAMMAR);
+            BOOST_SPIRIT_DEBUG_TRACE_RULE(ppendregion, TRACE_CPP_GRAMMAR);
+#endif
+        }
+
+    // start rule of this grammar
+        rule_type const& start() const
+        { return pp_statement; }
+    };
+
+    bool &found_eof;
+    TokenT &found_directive;
+    ContainerT &found_eoltokens;
+    
+    cpp_grammar(bool &found_eof_, TokenT &found_directive_, 
+            ContainerT &found_eoltokens_)
+    :   found_eof(found_eof_), 
+        found_directive(found_directive_),
+        found_eoltokens(found_eoltokens_)
+    { 
+        BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this, "cpp_grammar", 
+            TRACE_CPP_GRAMMAR); 
+    }
+
+#if BOOST_WAVE_DUMP_PARSE_TREE != 0
+// helper function and data to get readable names of the rules known to us
+    struct map_ruleid_to_name :
+        public std::map<boost::spirit::classic::parser_id, std::string> 
+    {
+        typedef std::map<boost::spirit::classic::parser_id, std::string> base_type;
+
+        void init_rule_id_to_name_map(cpp_grammar const &self)
+        {
+            struct {
+                int parser_id;
+                char const *rule_name;
+            } 
+            init_ruleid_name_map[] = {
+                { BOOST_WAVE_PP_STATEMENT_ID, "pp_statement" },
+//                 { BOOST_WAVE_INCLUDE_FILE_ID, "include_file" },
+//                 { BOOST_WAVE_SYSINCLUDE_FILE_ID, "system_include_file" },
+                { BOOST_WAVE_MACROINCLUDE_FILE_ID, "macro_include_file" },
+                { BOOST_WAVE_PLAIN_DEFINE_ID, "plain_define" },
+                { BOOST_WAVE_MACRO_PARAMETERS_ID, "macro_parameters" },
+                { BOOST_WAVE_MACRO_DEFINITION_ID, "macro_definition" },
+                { BOOST_WAVE_UNDEFINE_ID, "undefine" },
+                { BOOST_WAVE_IFDEF_ID, "ppifdef" },
+                { BOOST_WAVE_IFNDEF_ID, "ppifndef" },
+                { BOOST_WAVE_IF_ID, "ppif" },
+                { BOOST_WAVE_ELIF_ID, "ppelif" },
+//                 { BOOST_WAVE_ELSE_ID, "ppelse" },
+//                 { BOOST_WAVE_ENDIF_ID, "ppendif" },
+                { BOOST_WAVE_LINE_ID, "ppline" },
+                { BOOST_WAVE_ERROR_ID, "pperror" },
+                { BOOST_WAVE_WARNING_ID, "ppwarning" },
+                { BOOST_WAVE_PRAGMA_ID, "pppragma" },
+                { BOOST_WAVE_ILLFORMED_ID, "illformed" },
+                { BOOST_WAVE_PPSPACE_ID, "ppspace" },
+                { BOOST_WAVE_PPQUALIFIEDNAME_ID, "ppqualifiedname" },
+#if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
+                { BOOST_WAVE_REGION_ID, "ppregion" },
+                { BOOST_WAVE_ENDREGION_ID, "ppendregion" },
+#endif
+                { 0 }
+            };
+
+        // initialize parser_id to rule_name map
+            for (int i = 0; 0 != init_ruleid_name_map[i].parser_id; ++i)
+                base_type::insert(base_type::value_type(
+                    boost::spirit::classic::parser_id(init_ruleid_name_map[i].parser_id), 
+                    std::string(init_ruleid_name_map[i].rule_name))
+                );
+        }
+    };
+    mutable map_ruleid_to_name map_rule_id_to_name;
+#endif // WAVE_DUMP_PARSE_TREE != 0
+};
+
+///////////////////////////////////////////////////////////////////////////////
+#undef TRACE_CPP_GRAMMAR
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Special parse function generating a parse tree using a given node_factory.
+//
+///////////////////////////////////////////////////////////////////////////////
+template <typename NodeFactoryT, typename IteratorT, typename ParserT>
+inline boost::spirit::classic::tree_parse_info<IteratorT, NodeFactoryT>
+parsetree_parse(IteratorT const& first_, IteratorT const& last,
+    boost::spirit::classic::parser<ParserT> const& p)
+{
+    using namespace boost::spirit::classic;
+    
+    typedef pt_match_policy<IteratorT, NodeFactoryT> pt_match_policy_type;
+    typedef scanner_policies<iteration_policy, pt_match_policy_type>
+        scanner_policies_type;
+    typedef scanner<IteratorT, scanner_policies_type> scanner_type;
+
+    scanner_policies_type policies;
+    IteratorT first = first_;
+    scanner_type scan(first, last, policies);
+    tree_match<IteratorT, NodeFactoryT> hit = p.derived().parse(scan);
+    return tree_parse_info<IteratorT, NodeFactoryT>(
+        first, hit, hit && (first == last), hit.length(), hit.trees);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//  
+//  The following parse function is defined here, to allow the separation of 
+//  the compilation of the cpp_grammar from the function using it.
+//  
+///////////////////////////////////////////////////////////////////////////////
+
+#if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
+#define BOOST_WAVE_GRAMMAR_GEN_INLINE
+#else
+#define BOOST_WAVE_GRAMMAR_GEN_INLINE inline
+#endif 
+
+template <typename LexIteratorT, typename TokenContainerT>
+BOOST_WAVE_GRAMMAR_GEN_INLINE 
+boost::spirit::classic::tree_parse_info<
+    LexIteratorT, 
+    typename cpp_grammar_gen<LexIteratorT, TokenContainerT>::node_factory_type
+>
+cpp_grammar_gen<LexIteratorT, TokenContainerT>::parse_cpp_grammar (
+    LexIteratorT const &first, LexIteratorT const &last,
+    position_type const &act_pos, bool &found_eof,
+    token_type &found_directive, token_container_type &found_eoltokens)
+{
+    using namespace boost::spirit::classic;
+    using namespace boost::wave;
+    
+    cpp_grammar<token_type, TokenContainerT> g(found_eof, found_directive, found_eoltokens);
+    tree_parse_info<LexIteratorT, node_factory_type> hit = 
+        parsetree_parse<node_factory_type>(first, last, g);
+    
+#if BOOST_WAVE_DUMP_PARSE_TREE != 0
+    if (hit.match) {
+        tree_to_xml (BOOST_WAVE_DUMP_PARSE_TREE_OUT, hit.trees, "", 
+            g.map_rule_id_to_name, &token_type::get_token_id, 
+            &token_type::get_token_value);
+    }
+#endif
+
+    return hit;
+}
+
+#undef BOOST_WAVE_GRAMMAR_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_GRAMMAR_HPP_FEAEBC2E_2734_428B_A7CA_85E5A415E23E_INCLUDED)