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