cpp_predef_macros_grammar.hpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /*=============================================================================
  2. Boost.Wave: A Standard compliant C++ preprocessor library
  3. http://www.boost.org/
  4. Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost
  5. Software License, Version 1.0. (See accompanying file
  6. LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. =============================================================================*/
  8. #if !defined(CPP_PREDEF_MACROS_GRAMMAR_HPP_53858C9A_C202_4D60_AD92_DC9CAE4DBB43_INCLUDED)
  9. #define CPP_PREDEF_MACROS_GRAMMAR_HPP_53858C9A_C202_4D60_AD92_DC9CAE4DBB43_INCLUDED
  10. #include <boost/spirit/include/classic_core.hpp>
  11. #include <boost/spirit/include/classic_parse_tree.hpp>
  12. #include <boost/spirit/include/classic_confix.hpp>
  13. #include <boost/spirit/include/classic_lists.hpp>
  14. #include <boost/wave/wave_config.hpp>
  15. #include <boost/wave/token_ids.hpp>
  16. #include <boost/wave/grammars/cpp_predef_macros_gen.hpp>
  17. #include <boost/wave/util/pattern_parser.hpp>
  18. // this must occur after all of the includes and before any code appears
  19. #ifdef BOOST_HAS_ABI_HEADERS
  20. #include BOOST_ABI_PREFIX
  21. #endif
  22. ///////////////////////////////////////////////////////////////////////////////
  23. namespace boost {
  24. namespace wave {
  25. namespace grammars {
  26. ///////////////////////////////////////////////////////////////////////////////
  27. // define, whether the rule's should generate some debug output
  28. #define TRACE_PREDEF_MACROS_GRAMMAR \
  29. bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_PREDEF_MACROS_GRAMMAR) \
  30. /**/
  31. ///////////////////////////////////////////////////////////////////////////////
  32. // Encapsulation of the grammar for command line driven predefined macros.
  33. struct predefined_macros_grammar :
  34. public boost::spirit::classic::grammar<predefined_macros_grammar>
  35. {
  36. template <typename ScannerT>
  37. struct definition
  38. {
  39. // 'normal' (parse_tree generating) rule type
  40. typedef boost::spirit::classic::rule<
  41. ScannerT, boost::spirit::classic::dynamic_parser_tag>
  42. rule_type;
  43. rule_type plain_define, macro_definition, macro_parameters;
  44. definition(predefined_macros_grammar const &/*self*/)
  45. {
  46. // import the spirit and cpplexer namespaces here
  47. using namespace boost::spirit::classic;
  48. using namespace boost::wave;
  49. using namespace boost::wave::util;
  50. // set the rule id's for later use
  51. plain_define.set_id(BOOST_WAVE_PLAIN_DEFINE_ID);
  52. macro_parameters.set_id(BOOST_WAVE_MACRO_PARAMETERS_ID);
  53. macro_definition.set_id(BOOST_WAVE_MACRO_DEFINITION_ID);
  54. // recognizes command line defined macro syntax, i.e.
  55. // -DMACRO
  56. // -DMACRO=
  57. // -DMACRO=value
  58. // -DMACRO(x)
  59. // -DMACRO(x)=
  60. // -DMACRO(x)=value
  61. // This grammar resembles the overall structure of the cpp_grammar to
  62. // make it possible to reuse the parse tree traversal code
  63. plain_define
  64. = ( ch_p(T_IDENTIFIER)
  65. | pattern_p(KeywordTokenType,
  66. TokenTypeMask|PPTokenFlag)
  67. | pattern_p(OperatorTokenType|AltExtTokenType,
  68. ExtTokenTypeMask|PPTokenFlag) // and, bit_and etc.
  69. | pattern_p(BoolLiteralTokenType,
  70. TokenTypeMask|PPTokenFlag) // true/false
  71. )
  72. >> !macro_parameters
  73. >> !macro_definition
  74. ;
  75. // parameter list
  76. macro_parameters
  77. = confix_p(
  78. no_node_d[ch_p(T_LEFTPAREN) >> *ch_p(T_SPACE)],
  79. !list_p(
  80. ( ch_p(T_IDENTIFIER)
  81. | pattern_p(KeywordTokenType,
  82. TokenTypeMask|PPTokenFlag)
  83. | pattern_p(OperatorTokenType|AltExtTokenType,
  84. ExtTokenTypeMask|PPTokenFlag) // and, bit_and etc.
  85. | pattern_p(BoolLiteralTokenType,
  86. TokenTypeMask|PPTokenFlag) // true/false
  87. #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
  88. | ch_p(T_ELLIPSIS)
  89. #endif
  90. ),
  91. no_node_d
  92. [
  93. *ch_p(T_SPACE) >> ch_p(T_COMMA) >> *ch_p(T_SPACE)
  94. ]
  95. ),
  96. no_node_d[*ch_p(T_SPACE) >> ch_p(T_RIGHTPAREN)]
  97. )
  98. ;
  99. // macro body (anything left until eol)
  100. macro_definition
  101. = no_node_d[ch_p(T_ASSIGN)]
  102. >> *anychar_p
  103. ;
  104. BOOST_SPIRIT_DEBUG_TRACE_RULE(plain_define, TRACE_PREDEF_MACROS_GRAMMAR);
  105. BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_definition, TRACE_PREDEF_MACROS_GRAMMAR);
  106. BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_parameters, TRACE_PREDEF_MACROS_GRAMMAR);
  107. }
  108. // start rule of this grammar
  109. rule_type const& start() const
  110. { return plain_define; }
  111. };
  112. predefined_macros_grammar()
  113. {
  114. BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this,
  115. "predefined_macros_grammar", TRACE_PREDEF_MACROS_GRAMMAR);
  116. }
  117. };
  118. ///////////////////////////////////////////////////////////////////////////////
  119. #undef TRACE_PREDEF_MACROS_GRAMMAR
  120. ///////////////////////////////////////////////////////////////////////////////
  121. //
  122. // The following parse function is defined here, to allow the separation of
  123. // the compilation of the cpp_predefined_macros_grammar from the function
  124. // using it.
  125. //
  126. ///////////////////////////////////////////////////////////////////////////////
  127. #if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
  128. #define BOOST_WAVE_PREDEF_MACROS_GRAMMAR_GEN_INLINE
  129. #else
  130. #define BOOST_WAVE_PREDEF_MACROS_GRAMMAR_GEN_INLINE inline
  131. #endif
  132. template <typename LexIteratorT>
  133. BOOST_WAVE_PREDEF_MACROS_GRAMMAR_GEN_INLINE
  134. boost::spirit::classic::tree_parse_info<LexIteratorT>
  135. predefined_macros_grammar_gen<LexIteratorT>::parse_predefined_macro (
  136. LexIteratorT const &first, LexIteratorT const &last)
  137. {
  138. predefined_macros_grammar g;
  139. return boost::spirit::classic::pt_parse (first, last, g);
  140. }
  141. #undef BOOST_WAVE_PREDEF_MACROS_GRAMMAR_GEN_INLINE
  142. ///////////////////////////////////////////////////////////////////////////////
  143. } // namespace grammars
  144. } // namespace wave
  145. } // namespace boost
  146. // the suffix header occurs after all of the code
  147. #ifdef BOOST_HAS_ABI_HEADERS
  148. #include BOOST_ABI_SUFFIX
  149. #endif
  150. #endif // !defined(CPP_PREDEF_MACROS_GRAMMAR_HPP_53858C9A_C202_4D60_AD92_DC9CAE4DBB43_INCLUDED)