⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpp_grammar.hpp

📁 Boost provides free peer-reviewed portable C++ source libraries. We emphasize libraries that work
💻 HPP
📖 第 1 页 / 共 2 页
字号:
/*=============================================================================    Boost.Wave: A Standard compliant C++ preprocessor library    http://www.boost.org/    Copyright (c) 2001-2008 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)                        |   pattern_p(OperatorTokenType|AltExtTokenType,                                 ExtTokenTypeMask)   // and, bit_and etc.                        |   pattern_p(BoolLiteralTokenType, TokenTypeMask)  // 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)                            |   pattern_p(OperatorTokenType|AltExtTokenType,                                     ExtTokenTypeMask)   // and, bit_and etc.                            |   pattern_p(BoolLiteralTokenType, TokenTypeMask)  // 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

⌨️ 快捷键说明

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