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_PREDEF_MACROS_GRAMMAR_HPP_53858C9A_C202_4D60_AD92_DC9CAE4DBB43_INCLUDED) Chris@16: #define CPP_PREDEF_MACROS_GRAMMAR_HPP_53858C9A_C202_4D60_AD92_DC9CAE4DBB43_INCLUDED Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include 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: /////////////////////////////////////////////////////////////////////////////// Chris@16: // define, whether the rule's should generate some debug output Chris@16: #define TRACE_PREDEF_MACROS_GRAMMAR \ Chris@16: bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_PREDEF_MACROS_GRAMMAR) \ Chris@16: /**/ Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Encapsulation of the grammar for command line driven predefined macros. Chris@16: struct predefined_macros_grammar : Chris@16: public boost::spirit::classic::grammar Chris@16: { Chris@16: template Chris@16: struct definition Chris@16: { Chris@16: // 'normal' (parse_tree generating) rule type Chris@16: typedef boost::spirit::classic::rule< Chris@16: ScannerT, boost::spirit::classic::dynamic_parser_tag> Chris@16: rule_type; Chris@16: Chris@16: rule_type plain_define, macro_definition, macro_parameters; Chris@16: Chris@16: definition(predefined_macros_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: 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: Chris@16: // recognizes command line defined macro syntax, i.e. Chris@16: // -DMACRO Chris@16: // -DMACRO= Chris@16: // -DMACRO=value Chris@16: // -DMACRO(x) Chris@16: // -DMACRO(x)= Chris@16: // -DMACRO(x)=value Chris@16: Chris@16: // This grammar resembles the overall structure of the cpp_grammar to Chris@16: // make it possible to reuse the parse tree traversal code Chris@16: plain_define 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: >> !macro_parameters Chris@16: >> !macro_definition Chris@16: ; Chris@16: Chris@16: // parameter list Chris@16: macro_parameters Chris@16: = confix_p( Chris@16: no_node_d[ch_p(T_LEFTPAREN) >> *ch_p(T_SPACE)], 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 Chris@16: [ Chris@16: *ch_p(T_SPACE) >> ch_p(T_COMMA) >> *ch_p(T_SPACE) Chris@16: ] Chris@16: ), Chris@16: no_node_d[*ch_p(T_SPACE) >> 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[ch_p(T_ASSIGN)] Chris@16: >> *anychar_p Chris@16: ; Chris@16: Chris@16: BOOST_SPIRIT_DEBUG_TRACE_RULE(plain_define, TRACE_PREDEF_MACROS_GRAMMAR); Chris@16: BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_definition, TRACE_PREDEF_MACROS_GRAMMAR); Chris@16: BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_parameters, TRACE_PREDEF_MACROS_GRAMMAR); Chris@16: } Chris@16: Chris@16: // start rule of this grammar Chris@16: rule_type const& start() const Chris@16: { return plain_define; } Chris@16: }; Chris@16: Chris@16: predefined_macros_grammar() Chris@16: { Chris@16: BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this, Chris@16: "predefined_macros_grammar", TRACE_PREDEF_MACROS_GRAMMAR); Chris@16: } Chris@16: Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: #undef TRACE_PREDEF_MACROS_GRAMMAR 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_predefined_macros_grammar from the function Chris@16: // using it. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: #if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0 Chris@16: #define BOOST_WAVE_PREDEF_MACROS_GRAMMAR_GEN_INLINE Chris@16: #else Chris@16: #define BOOST_WAVE_PREDEF_MACROS_GRAMMAR_GEN_INLINE inline Chris@16: #endif Chris@16: Chris@16: template Chris@16: BOOST_WAVE_PREDEF_MACROS_GRAMMAR_GEN_INLINE Chris@16: boost::spirit::classic::tree_parse_info Chris@16: predefined_macros_grammar_gen::parse_predefined_macro ( Chris@16: LexIteratorT const &first, LexIteratorT const &last) Chris@16: { Chris@16: predefined_macros_grammar g; Chris@16: return boost::spirit::classic::pt_parse (first, last, g); Chris@16: } Chris@16: Chris@16: #undef BOOST_WAVE_PREDEF_MACROS_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_PREDEF_MACROS_GRAMMAR_HPP_53858C9A_C202_4D60_AD92_DC9CAE4DBB43_INCLUDED)