| /*============================================================================= |
| Boost.Wave: A Standard compliant C++ preprocessor library |
| |
| http://www.boost.org/ |
| |
| Copyright (c) 2001-2009 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_PREDEF_MACROS_GRAMMAR_HPP_53858C9A_C202_4D60_AD92_DC9CAE4DBB43_INCLUDED) |
| #define CPP_PREDEF_MACROS_GRAMMAR_HPP_53858C9A_C202_4D60_AD92_DC9CAE4DBB43_INCLUDED |
| |
| #include <boost/spirit/include/classic_core.hpp> |
| #include <boost/spirit/include/classic_parse_tree.hpp> |
| #include <boost/spirit/include/classic_confix.hpp> |
| #include <boost/spirit/include/classic_lists.hpp> |
| |
| #include <boost/wave/wave_config.hpp> |
| #include <boost/wave/token_ids.hpp> |
| #include <boost/wave/grammars/cpp_predef_macros_gen.hpp> |
| #include <boost/wave/util/pattern_parser.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 { |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // define, whether the rule's should generate some debug output |
| #define TRACE_PREDEF_MACROS_GRAMMAR \ |
| bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_PREDEF_MACROS_GRAMMAR) \ |
| /**/ |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // Encapsulation of the grammar for command line driven predefined macros. |
| struct predefined_macros_grammar : |
| public boost::spirit::classic::grammar<predefined_macros_grammar> |
| { |
| template <typename ScannerT> |
| struct definition |
| { |
| // 'normal' (parse_tree generating) rule type |
| typedef boost::spirit::classic::rule< |
| ScannerT, boost::spirit::classic::dynamic_parser_tag> |
| rule_type; |
| |
| rule_type plain_define, macro_definition, macro_parameters; |
| |
| definition(predefined_macros_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 |
| 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); |
| |
| // recognizes command line defined macro syntax, i.e. |
| // -DMACRO |
| // -DMACRO= |
| // -DMACRO=value |
| // -DMACRO(x) |
| // -DMACRO(x)= |
| // -DMACRO(x)=value |
| |
| // This grammar resembles the overall structure of the cpp_grammar to |
| // make it possible to reuse the parse tree traversal code |
| plain_define |
| = ( ch_p(T_IDENTIFIER) |
| | pattern_p(KeywordTokenType, TokenTypeMask) |
| | pattern_p(OperatorTokenType|AltExtTokenType, |
| ExtTokenTypeMask) // and, bit_and etc. |
| | pattern_p(BoolLiteralTokenType, TokenTypeMask) // true/false |
| ) |
| >> !macro_parameters |
| >> !macro_definition |
| ; |
| |
| // parameter list |
| macro_parameters |
| = confix_p( |
| no_node_d[ch_p(T_LEFTPAREN) >> *ch_p(T_SPACE)], |
| !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 |
| [ |
| *ch_p(T_SPACE) >> ch_p(T_COMMA) >> *ch_p(T_SPACE) |
| ] |
| ), |
| no_node_d[*ch_p(T_SPACE) >> ch_p(T_RIGHTPAREN)] |
| ) |
| ; |
| |
| // macro body (anything left until eol) |
| macro_definition |
| = no_node_d[ch_p(T_ASSIGN)] |
| >> *anychar_p |
| ; |
| |
| BOOST_SPIRIT_DEBUG_TRACE_RULE(plain_define, TRACE_PREDEF_MACROS_GRAMMAR); |
| BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_definition, TRACE_PREDEF_MACROS_GRAMMAR); |
| BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_parameters, TRACE_PREDEF_MACROS_GRAMMAR); |
| } |
| |
| // start rule of this grammar |
| rule_type const& start() const |
| { return plain_define; } |
| }; |
| |
| predefined_macros_grammar() |
| { |
| BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this, |
| "predefined_macros_grammar", TRACE_PREDEF_MACROS_GRAMMAR); |
| } |
| |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| #undef TRACE_PREDEF_MACROS_GRAMMAR |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // |
| // The following parse function is defined here, to allow the separation of |
| // the compilation of the cpp_predefined_macros_grammar from the function |
| // using it. |
| // |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| #if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0 |
| #define BOOST_WAVE_PREDEF_MACROS_GRAMMAR_GEN_INLINE |
| #else |
| #define BOOST_WAVE_PREDEF_MACROS_GRAMMAR_GEN_INLINE inline |
| #endif |
| |
| template <typename LexIteratorT> |
| BOOST_WAVE_PREDEF_MACROS_GRAMMAR_GEN_INLINE |
| boost::spirit::classic::tree_parse_info<LexIteratorT> |
| predefined_macros_grammar_gen<LexIteratorT>::parse_predefined_macro ( |
| LexIteratorT const &first, LexIteratorT const &last) |
| { |
| predefined_macros_grammar g; |
| return boost::spirit::classic::pt_parse (first, last, g); |
| } |
| |
| #undef BOOST_WAVE_PREDEF_MACROS_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_PREDEF_MACROS_GRAMMAR_HPP_53858C9A_C202_4D60_AD92_DC9CAE4DBB43_INCLUDED) |