cpp_defined_grammar.hpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  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_DEFINED_GRAMMAR_HPP_F48287B2_DC67_40A8_B4A1_800EFBD67869_INCLUDED)
  9. #define CPP_DEFINED_GRAMMAR_HPP_F48287B2_DC67_40A8_B4A1_800EFBD67869_INCLUDED
  10. #include <boost/wave/wave_config.hpp>
  11. #include <boost/assert.hpp>
  12. #include <boost/spirit/include/classic_core.hpp>
  13. #include <boost/spirit/include/classic_closure.hpp>
  14. #include <boost/spirit/include/classic_assign_actor.hpp>
  15. #include <boost/spirit/include/classic_push_back_actor.hpp>
  16. #include <boost/wave/token_ids.hpp>
  17. #include <boost/wave/util/pattern_parser.hpp>
  18. #include <boost/wave/grammars/cpp_defined_grammar_gen.hpp>
  19. #if !defined(spirit_append_actor)
  20. #define spirit_append_actor(actor) boost::spirit::classic::push_back_a(actor)
  21. #define spirit_assign_actor(actor) boost::spirit::classic::assign_a(actor)
  22. #endif // !defined(spirit_append_actor)
  23. // this must occur after all of the includes and before any code appears
  24. #ifdef BOOST_HAS_ABI_HEADERS
  25. #include BOOST_ABI_PREFIX
  26. #endif
  27. ///////////////////////////////////////////////////////////////////////////////
  28. namespace boost {
  29. namespace wave {
  30. namespace grammars {
  31. ///////////////////////////////////////////////////////////////////////////////
  32. // define, whether the rule's should generate some debug output
  33. #define TRACE_CPP_DEFINED_GRAMMAR \
  34. bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_DEFINED_GRAMMAR) \
  35. /**/
  36. template <typename ContainerT>
  37. struct defined_grammar :
  38. public boost::spirit::classic::grammar<defined_grammar<ContainerT> >
  39. {
  40. defined_grammar(ContainerT &result_seq_)
  41. : result_seq(result_seq_)
  42. {
  43. BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this, "defined_grammar",
  44. TRACE_CPP_DEFINED_GRAMMAR);
  45. }
  46. template <typename ScannerT>
  47. struct definition
  48. {
  49. typedef boost::spirit::classic::rule<ScannerT> rule_t;
  50. rule_t defined_op;
  51. rule_t identifier;
  52. definition(defined_grammar const &self)
  53. {
  54. using namespace boost::spirit::classic;
  55. using namespace boost::wave;
  56. using namespace boost::wave::util;
  57. defined_op // parens not required, see C++ standard 16.1.1
  58. = ch_p(T_IDENTIFIER) // token contains 'defined'
  59. >> (
  60. ( ch_p(T_LEFTPAREN)
  61. >> identifier
  62. >> ch_p(T_RIGHTPAREN)
  63. )
  64. | identifier
  65. )
  66. ;
  67. identifier
  68. = ch_p(T_IDENTIFIER)
  69. [
  70. spirit_append_actor(self.result_seq)
  71. ]
  72. | pattern_p(KeywordTokenType, TokenTypeMask|PPTokenFlag)
  73. [
  74. spirit_append_actor(self.result_seq)
  75. ]
  76. | pattern_p(OperatorTokenType|AltExtTokenType,
  77. ExtTokenTypeMask|PPTokenFlag)
  78. [
  79. spirit_append_actor(self.result_seq)
  80. ]
  81. | pattern_p(BoolLiteralTokenType, TokenTypeMask|PPTokenFlag)
  82. [
  83. spirit_append_actor(self.result_seq)
  84. ]
  85. ;
  86. BOOST_SPIRIT_DEBUG_TRACE_RULE(defined_op, TRACE_CPP_DEFINED_GRAMMAR);
  87. BOOST_SPIRIT_DEBUG_TRACE_RULE(identifier, TRACE_CPP_DEFINED_GRAMMAR);
  88. }
  89. // start rule of this grammar
  90. rule_t const& start() const
  91. { return defined_op; }
  92. };
  93. ContainerT &result_seq;
  94. };
  95. ///////////////////////////////////////////////////////////////////////////////
  96. #undef TRACE_CPP_DEFINED_GRAMMAR
  97. ///////////////////////////////////////////////////////////////////////////////
  98. //
  99. // The following parse function is defined here, to allow the separation of
  100. // the compilation of the defined_grammar from the function
  101. // using it.
  102. //
  103. ///////////////////////////////////////////////////////////////////////////////
  104. #if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
  105. #define BOOST_WAVE_DEFINED_GRAMMAR_GEN_INLINE
  106. #else
  107. #define BOOST_WAVE_DEFINED_GRAMMAR_GEN_INLINE inline
  108. #endif
  109. // The parse_operator_define function is instantiated manually twice to
  110. // simplify the explicit specialization of this template. This way the user
  111. // has only to specify one template parameter (the lexer type) to correctly
  112. // formulate the required explicit specialization.
  113. // This results in no code overhead, because otherwise the function would be
  114. // generated by the compiler twice anyway.
  115. template <typename LexIteratorT>
  116. BOOST_WAVE_DEFINED_GRAMMAR_GEN_INLINE
  117. boost::spirit::classic::parse_info<
  118. typename defined_grammar_gen<LexIteratorT>::iterator1_type
  119. >
  120. defined_grammar_gen<LexIteratorT>::parse_operator_defined (
  121. iterator1_type const &first, iterator1_type const &last,
  122. token_sequence_type &found_qualified_name)
  123. {
  124. using namespace boost::spirit::classic;
  125. using namespace boost::wave;
  126. defined_grammar<token_sequence_type> g(found_qualified_name);
  127. return boost::spirit::classic::parse (
  128. first, last, g, ch_p(T_SPACE) | ch_p(T_CCOMMENT));
  129. }
  130. template <typename LexIteratorT>
  131. BOOST_WAVE_DEFINED_GRAMMAR_GEN_INLINE
  132. boost::spirit::classic::parse_info<
  133. typename defined_grammar_gen<LexIteratorT>::iterator2_type
  134. >
  135. defined_grammar_gen<LexIteratorT>::parse_operator_defined (
  136. iterator2_type const &first, iterator2_type const &last,
  137. token_sequence_type &found_qualified_name)
  138. {
  139. using namespace boost::spirit::classic;
  140. using namespace boost::wave;
  141. defined_grammar<token_sequence_type> g(found_qualified_name);
  142. return boost::spirit::classic::parse (
  143. first, last, g, ch_p(T_SPACE) | ch_p(T_CCOMMENT));
  144. }
  145. #undef BOOST_WAVE_DEFINED_GRAMMAR_GEN_INLINE
  146. ///////////////////////////////////////////////////////////////////////////////
  147. } // namespace grammars
  148. } // namespace wave
  149. } // namespace boost
  150. // the suffix header occurs after all of the code
  151. #ifdef BOOST_HAS_ABI_HEADERS
  152. #include BOOST_ABI_SUFFIX
  153. #endif
  154. #endif // !defined(CPP_DEFINED_GRAMMAR_HPP_F48287B2_DC67_40A8_B4A1_800EFBD67869_INCLUDED)