]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | ||
20effc67 TL |
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 | |
7c673cae FG |
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 { | |
b32b8144 | 38 | namespace wave { |
7c673cae FG |
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 | { | |
51 | defined_grammar(ContainerT &result_seq_) | |
52 | : result_seq(result_seq_) | |
53 | { | |
b32b8144 | 54 | BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this, "defined_grammar", |
7c673cae FG |
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 | ||
66 | 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) | |
b32b8144 | 87 | ] |
7c673cae FG |
88 | | pattern_p(KeywordTokenType, TokenTypeMask|PPTokenFlag) |
89 | [ | |
90 | spirit_append_actor(self.result_seq) | |
b32b8144 FG |
91 | ] |
92 | | pattern_p(OperatorTokenType|AltExtTokenType, | |
7c673cae FG |
93 | ExtTokenTypeMask|PPTokenFlag) |
94 | [ | |
95 | spirit_append_actor(self.result_seq) | |
b32b8144 | 96 | ] |
7c673cae FG |
97 | | pattern_p(BoolLiteralTokenType, TokenTypeMask|PPTokenFlag) |
98 | [ | |
99 | spirit_append_actor(self.result_seq) | |
b32b8144 | 100 | ] |
7c673cae FG |
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 | ||
20effc67 | 107 | // start rule of this grammar |
7c673cae FG |
108 | 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 | /////////////////////////////////////////////////////////////////////////////// | |
b32b8144 FG |
119 | // |
120 | // The following parse function is defined here, to allow the separation of | |
121 | // the compilation of the defined_grammar from the function | |
7c673cae | 122 | // using it. |
b32b8144 | 123 | // |
7c673cae FG |
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 | |
b32b8144 | 130 | #endif |
7c673cae | 131 | |
b32b8144 FG |
132 | // The parse_operator_define function is instantiated manually twice to |
133 | // simplify the explicit specialization of this template. This way the user | |
7c673cae FG |
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> | |
b32b8144 | 140 | BOOST_WAVE_DEFINED_GRAMMAR_GEN_INLINE |
7c673cae FG |
141 | boost::spirit::classic::parse_info< |
142 | typename defined_grammar_gen<LexIteratorT>::iterator1_type | |
143 | > | |
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; | |
b32b8144 | 150 | |
7c673cae FG |
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> | |
b32b8144 | 157 | BOOST_WAVE_DEFINED_GRAMMAR_GEN_INLINE |
7c673cae FG |
158 | boost::spirit::classic::parse_info< |
159 | typename defined_grammar_gen<LexIteratorT>::iterator2_type | |
160 | > | |
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; | |
b32b8144 | 167 | |
7c673cae FG |
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 | ||
20effc67 | 185 | #endif // !defined(BOOST_CPP_DEFINED_GRAMMAR_HPP_F48287B2_DC67_40A8_B4A1_800EFBD67869_INCLUDED) |