• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Boost.Wave: A Standard compliant C++ preprocessor library
3 
4     http://www.boost.org/
5 
6     Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost
7     Software License, Version 1.0. (See accompanying file
8     LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 =============================================================================*/
10 
11 #if !defined(BOOST_CPP_DEFINED_GRAMMAR_HPP_F48287B2_DC67_40A8_B4A1_800EFBD67869_INCLUDED)
12 #define BOOST_CPP_DEFINED_GRAMMAR_HPP_F48287B2_DC67_40A8_B4A1_800EFBD67869_INCLUDED
13 
14 #include <boost/wave/wave_config.hpp>
15 
16 #include <boost/assert.hpp>
17 #include <boost/spirit/include/classic_core.hpp>
18 #include <boost/spirit/include/classic_closure.hpp>
19 #include <boost/spirit/include/classic_assign_actor.hpp>
20 #include <boost/spirit/include/classic_push_back_actor.hpp>
21 
22 #include <boost/wave/token_ids.hpp>
23 #include <boost/wave/util/pattern_parser.hpp>
24 #include <boost/wave/grammars/cpp_defined_grammar_gen.hpp>
25 
26 #if !defined(spirit_append_actor)
27 #define spirit_append_actor(actor) boost::spirit::classic::push_back_a(actor)
28 #define spirit_assign_actor(actor) boost::spirit::classic::assign_a(actor)
29 #endif // !defined(spirit_append_actor)
30 
31 // this must occur after all of the includes and before any code appears
32 #ifdef BOOST_HAS_ABI_HEADERS
33 #include BOOST_ABI_PREFIX
34 #endif
35 
36 ///////////////////////////////////////////////////////////////////////////////
37 namespace boost {
38 namespace wave {
39 namespace grammars {
40 
41 ///////////////////////////////////////////////////////////////////////////////
42 //  define, whether the rule's should generate some debug output
43 #define TRACE_CPP_DEFINED_GRAMMAR \
44     bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_DEFINED_GRAMMAR) \
45     /**/
46 
47 template <typename ContainerT>
48 struct defined_grammar :
49     public boost::spirit::classic::grammar<defined_grammar<ContainerT> >
50 {
defined_grammarboost::wave::grammars::defined_grammar51     defined_grammar(ContainerT &result_seq_)
52     :   result_seq(result_seq_)
53     {
54         BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this, "defined_grammar",
55             TRACE_CPP_DEFINED_GRAMMAR);
56     }
57 
58     template <typename ScannerT>
59     struct definition
60     {
61         typedef boost::spirit::classic::rule<ScannerT> rule_t;
62 
63         rule_t defined_op;
64         rule_t identifier;
65 
definitionboost::wave::grammars::defined_grammar::definition66         definition(defined_grammar const &self)
67         {
68             using namespace boost::spirit::classic;
69             using namespace boost::wave;
70             using namespace boost::wave::util;
71 
72             defined_op      // parens not required, see C++ standard 16.1.1
73                 =   ch_p(T_IDENTIFIER)      // token contains 'defined'
74                     >>  (
75                             (   ch_p(T_LEFTPAREN)
76                                 >>  identifier
77                                 >>  ch_p(T_RIGHTPAREN)
78                             )
79                             |   identifier
80                         )
81                 ;
82 
83             identifier
84                 =   ch_p(T_IDENTIFIER)
85                     [
86                         spirit_append_actor(self.result_seq)
87                     ]
88                 |   pattern_p(KeywordTokenType, TokenTypeMask|PPTokenFlag)
89                     [
90                         spirit_append_actor(self.result_seq)
91                     ]
92                 |   pattern_p(OperatorTokenType|AltExtTokenType,
93                         ExtTokenTypeMask|PPTokenFlag)
94                     [
95                         spirit_append_actor(self.result_seq)
96                     ]
97                 |   pattern_p(BoolLiteralTokenType, TokenTypeMask|PPTokenFlag)
98                     [
99                         spirit_append_actor(self.result_seq)
100                     ]
101                 ;
102 
103             BOOST_SPIRIT_DEBUG_TRACE_RULE(defined_op, TRACE_CPP_DEFINED_GRAMMAR);
104             BOOST_SPIRIT_DEBUG_TRACE_RULE(identifier, TRACE_CPP_DEFINED_GRAMMAR);
105         }
106 
107     // start rule of this grammar
startboost::wave::grammars::defined_grammar::definition108         rule_t const& start() const
109         { return defined_op; }
110     };
111 
112     ContainerT &result_seq;
113 };
114 
115 ///////////////////////////////////////////////////////////////////////////////
116 #undef TRACE_CPP_DEFINED_GRAMMAR
117 
118 ///////////////////////////////////////////////////////////////////////////////
119 //
120 //  The following parse function is defined here, to allow the separation of
121 //  the compilation of the defined_grammar from the function
122 //  using it.
123 //
124 ///////////////////////////////////////////////////////////////////////////////
125 
126 #if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
127 #define BOOST_WAVE_DEFINED_GRAMMAR_GEN_INLINE
128 #else
129 #define BOOST_WAVE_DEFINED_GRAMMAR_GEN_INLINE inline
130 #endif
131 
132 //  The parse_operator_define function is instantiated manually twice to
133 //  simplify the explicit specialization of this template. This way the user
134 //  has only to specify one template parameter (the lexer type) to correctly
135 //  formulate the required explicit specialization.
136 //  This results in no code overhead, because otherwise the function would be
137 //  generated by the compiler twice anyway.
138 
139 template <typename LexIteratorT>
140 BOOST_WAVE_DEFINED_GRAMMAR_GEN_INLINE
141 boost::spirit::classic::parse_info<
142     typename defined_grammar_gen<LexIteratorT>::iterator1_type
143 >
parse_operator_defined(iterator1_type const & first,iterator1_type const & last,token_sequence_type & found_qualified_name)144 defined_grammar_gen<LexIteratorT>::parse_operator_defined (
145     iterator1_type const &first, iterator1_type const &last,
146     token_sequence_type &found_qualified_name)
147 {
148     using namespace boost::spirit::classic;
149     using namespace boost::wave;
150 
151     defined_grammar<token_sequence_type> g(found_qualified_name);
152     return boost::spirit::classic::parse (
153         first, last, g, ch_p(T_SPACE) | ch_p(T_CCOMMENT));
154 }
155 
156 template <typename LexIteratorT>
157 BOOST_WAVE_DEFINED_GRAMMAR_GEN_INLINE
158 boost::spirit::classic::parse_info<
159     typename defined_grammar_gen<LexIteratorT>::iterator2_type
160 >
parse_operator_defined(iterator2_type const & first,iterator2_type const & last,token_sequence_type & found_qualified_name)161 defined_grammar_gen<LexIteratorT>::parse_operator_defined (
162     iterator2_type const &first, iterator2_type const &last,
163     token_sequence_type &found_qualified_name)
164 {
165     using namespace boost::spirit::classic;
166     using namespace boost::wave;
167 
168     defined_grammar<token_sequence_type> g(found_qualified_name);
169     return boost::spirit::classic::parse (
170         first, last, g, ch_p(T_SPACE) | ch_p(T_CCOMMENT));
171 }
172 
173 #undef BOOST_WAVE_DEFINED_GRAMMAR_GEN_INLINE
174 
175 ///////////////////////////////////////////////////////////////////////////////
176 }   // namespace grammars
177 }   // namespace wave
178 }   // namespace boost
179 
180 // the suffix header occurs after all of the code
181 #ifdef BOOST_HAS_ABI_HEADERS
182 #include BOOST_ABI_SUFFIX
183 #endif
184 
185 #endif // !defined(BOOST_CPP_DEFINED_GRAMMAR_HPP_F48287B2_DC67_40A8_B4A1_800EFBD67869_INCLUDED)
186