Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/wave/grammars/cpp_grammar.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
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(CPP_GRAMMAR_HPP_FEAEBC2E_2734_428B_A7CA_85E5A415E23E_INCLUDED) | |
12 #define CPP_GRAMMAR_HPP_FEAEBC2E_2734_428B_A7CA_85E5A415E23E_INCLUDED | |
13 | |
14 #include <boost/spirit/include/classic_core.hpp> | |
15 #include <boost/spirit/include/classic_parse_tree.hpp> | |
16 #include <boost/spirit/include/classic_parse_tree_utils.hpp> | |
17 #include <boost/spirit/include/classic_confix.hpp> | |
18 #include <boost/spirit/include/classic_lists.hpp> | |
19 | |
20 #include <boost/wave/wave_config.hpp> | |
21 #include <boost/pool/pool_alloc.hpp> | |
22 | |
23 #if BOOST_WAVE_DUMP_PARSE_TREE != 0 | |
24 #include <map> | |
25 #include <boost/spirit/include/classic_tree_to_xml.hpp> | |
26 #endif | |
27 | |
28 #include <boost/wave/token_ids.hpp> | |
29 #include <boost/wave/grammars/cpp_grammar_gen.hpp> | |
30 #include <boost/wave/util/pattern_parser.hpp> | |
31 | |
32 #include <boost/wave/cpp_exceptions.hpp> | |
33 | |
34 // this must occur after all of the includes and before any code appears | |
35 #ifdef BOOST_HAS_ABI_HEADERS | |
36 #include BOOST_ABI_PREFIX | |
37 #endif | |
38 | |
39 /////////////////////////////////////////////////////////////////////////////// | |
40 namespace boost { | |
41 namespace wave { | |
42 namespace grammars { | |
43 | |
44 namespace impl { | |
45 | |
46 /////////////////////////////////////////////////////////////////////////////// | |
47 // | |
48 // store_found_eof | |
49 // | |
50 // The store_found_eof functor sets a given flag if the T_EOF token was | |
51 // found during the parsing process | |
52 // | |
53 /////////////////////////////////////////////////////////////////////////////// | |
54 | |
55 struct store_found_eof { | |
56 | |
57 store_found_eof(bool &found_eof_) : found_eof(found_eof_) {} | |
58 | |
59 template <typename TokenT> | |
60 void operator()(TokenT const &/*token*/) const | |
61 { | |
62 found_eof = true; | |
63 } | |
64 | |
65 bool &found_eof; | |
66 }; | |
67 | |
68 /////////////////////////////////////////////////////////////////////////////// | |
69 // | |
70 // store_found_directive | |
71 // | |
72 // The store_found_directive functor stores the token_id of the recognized | |
73 // pp directive | |
74 // | |
75 /////////////////////////////////////////////////////////////////////////////// | |
76 | |
77 template <typename TokenT> | |
78 struct store_found_directive { | |
79 | |
80 store_found_directive(TokenT &found_directive_) | |
81 : found_directive(found_directive_) {} | |
82 | |
83 void operator()(TokenT const &token) const | |
84 { | |
85 found_directive = token; | |
86 } | |
87 | |
88 TokenT &found_directive; | |
89 }; | |
90 | |
91 /////////////////////////////////////////////////////////////////////////////// | |
92 // | |
93 // store_found_eoltokens | |
94 // | |
95 // The store_found_eoltokens functor stores the token sequence of the | |
96 // line ending for a particular pp directive | |
97 // | |
98 /////////////////////////////////////////////////////////////////////////////// | |
99 | |
100 template <typename ContainerT> | |
101 struct store_found_eoltokens { | |
102 | |
103 store_found_eoltokens(ContainerT &found_eoltokens_) | |
104 : found_eoltokens(found_eoltokens_) {} | |
105 | |
106 template <typename IteratorT> | |
107 void operator()(IteratorT const &first, IteratorT const& last) const | |
108 { | |
109 std::copy(first, last, | |
110 std::inserter(found_eoltokens, found_eoltokens.end())); | |
111 } | |
112 | |
113 ContainerT &found_eoltokens; | |
114 }; | |
115 | |
116 /////////////////////////////////////////////////////////////////////////////// | |
117 // | |
118 // flush_underlying_parser | |
119 // | |
120 // The flush_underlying_parser flushes the underlying | |
121 // multi_pass_iterator during the normal parsing process. This is | |
122 // used at certain points during the parsing process, when it is | |
123 // clear, that no backtracking is needed anymore and the input | |
124 // gathered so far may be discarded. | |
125 // | |
126 /////////////////////////////////////////////////////////////////////////////// | |
127 struct flush_underlying_parser | |
128 : public boost::spirit::classic::parser<flush_underlying_parser> | |
129 { | |
130 typedef flush_underlying_parser this_t; | |
131 | |
132 template <typename ScannerT> | |
133 typename boost::spirit::classic::parser_result<this_t, ScannerT>::type | |
134 parse(ScannerT const& scan) const | |
135 { | |
136 scan.first.clear_queue(); | |
137 return scan.empty_match(); | |
138 } | |
139 }; | |
140 | |
141 flush_underlying_parser const | |
142 flush_underlying_parser_p = flush_underlying_parser(); | |
143 | |
144 } // anonymous namespace | |
145 | |
146 /////////////////////////////////////////////////////////////////////////////// | |
147 // define, whether the rule's should generate some debug output | |
148 #define TRACE_CPP_GRAMMAR \ | |
149 bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_CPP_GRAMMAR) \ | |
150 /**/ | |
151 | |
152 /////////////////////////////////////////////////////////////////////////////// | |
153 // Encapsulation of the C++ preprocessor grammar. | |
154 template <typename TokenT, typename ContainerT> | |
155 struct cpp_grammar : | |
156 public boost::spirit::classic::grammar<cpp_grammar<TokenT, ContainerT> > | |
157 { | |
158 typedef typename TokenT::position_type position_type; | |
159 typedef cpp_grammar<TokenT, ContainerT> grammar_type; | |
160 typedef impl::store_found_eof store_found_eof_type; | |
161 typedef impl::store_found_directive<TokenT> store_found_directive_type; | |
162 typedef impl::store_found_eoltokens<ContainerT> store_found_eoltokens_type; | |
163 | |
164 template <typename ScannerT> | |
165 struct definition | |
166 { | |
167 // non-parse_tree generating rule type | |
168 typedef typename ScannerT::iteration_policy_t iteration_policy_t; | |
169 typedef boost::spirit::classic::match_policy match_policy_t; | |
170 typedef typename ScannerT::action_policy_t action_policy_t; | |
171 typedef | |
172 boost::spirit::classic::scanner_policies< | |
173 iteration_policy_t, match_policy_t, action_policy_t> | |
174 policies_t; | |
175 typedef | |
176 boost::spirit::classic::scanner<typename ScannerT::iterator_t, policies_t> | |
177 non_tree_scanner_t; | |
178 typedef | |
179 boost::spirit::classic::rule< | |
180 non_tree_scanner_t, boost::spirit::classic::dynamic_parser_tag> | |
181 no_tree_rule_type; | |
182 | |
183 // 'normal' (parse_tree generating) rule type | |
184 typedef | |
185 boost::spirit::classic::rule< | |
186 ScannerT, boost::spirit::classic::dynamic_parser_tag> | |
187 rule_type; | |
188 | |
189 rule_type pp_statement, macro_include_file; | |
190 // rule_type include_file, system_include_file; | |
191 rule_type plain_define, macro_definition, macro_parameters; | |
192 rule_type undefine; | |
193 rule_type ppifdef, ppifndef, ppif, ppelif; | |
194 // rule_type ppelse, ppendif; | |
195 rule_type ppline; | |
196 rule_type pperror; | |
197 rule_type ppwarning; | |
198 rule_type pppragma; | |
199 rule_type illformed; | |
200 rule_type ppqualifiedname; | |
201 rule_type eol_tokens; | |
202 no_tree_rule_type ppsp; | |
203 #if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0 | |
204 rule_type ppregion; | |
205 rule_type ppendregion; | |
206 #endif | |
207 | |
208 definition(cpp_grammar const &self) | |
209 { | |
210 // import the spirit and cpplexer namespaces here | |
211 using namespace boost::spirit::classic; | |
212 using namespace boost::wave; | |
213 using namespace boost::wave::util; | |
214 | |
215 // set the rule id's for later use | |
216 pp_statement.set_id(BOOST_WAVE_PP_STATEMENT_ID); | |
217 // include_file.set_id(BOOST_WAVE_INCLUDE_FILE_ID); | |
218 // system_include_file.set_id(BOOST_WAVE_SYSINCLUDE_FILE_ID); | |
219 macro_include_file.set_id(BOOST_WAVE_MACROINCLUDE_FILE_ID); | |
220 plain_define.set_id(BOOST_WAVE_PLAIN_DEFINE_ID); | |
221 macro_parameters.set_id(BOOST_WAVE_MACRO_PARAMETERS_ID); | |
222 macro_definition.set_id(BOOST_WAVE_MACRO_DEFINITION_ID); | |
223 undefine.set_id(BOOST_WAVE_UNDEFINE_ID); | |
224 ppifdef.set_id(BOOST_WAVE_IFDEF_ID); | |
225 ppifndef.set_id(BOOST_WAVE_IFNDEF_ID); | |
226 ppif.set_id(BOOST_WAVE_IF_ID); | |
227 ppelif.set_id(BOOST_WAVE_ELIF_ID); | |
228 // ppelse.set_id(BOOST_WAVE_ELSE_ID); | |
229 // ppendif.set_id(BOOST_WAVE_ENDIF_ID); | |
230 ppline.set_id(BOOST_WAVE_LINE_ID); | |
231 pperror.set_id(BOOST_WAVE_ERROR_ID); | |
232 ppwarning.set_id(BOOST_WAVE_WARNING_ID); | |
233 pppragma.set_id(BOOST_WAVE_PRAGMA_ID); | |
234 illformed.set_id(BOOST_WAVE_ILLFORMED_ID); | |
235 ppsp.set_id(BOOST_WAVE_PPSPACE_ID); | |
236 ppqualifiedname.set_id(BOOST_WAVE_PPQUALIFIEDNAME_ID); | |
237 #if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0 | |
238 ppregion.set_id(BOOST_WAVE_REGION_ID); | |
239 ppendregion.set_id(BOOST_WAVE_ENDREGION_ID); | |
240 #endif | |
241 | |
242 #if BOOST_WAVE_DUMP_PARSE_TREE != 0 | |
243 self.map_rule_id_to_name.init_rule_id_to_name_map(self); | |
244 #endif | |
245 | |
246 // recognizes preprocessor directives only | |
247 | |
248 // C++ standard 16.1: A preprocessing directive consists of a sequence | |
249 // of preprocessing tokens. The first token in the sequence is # | |
250 // preprocessing token that is either the first character in the source | |
251 // file (optionally after white space containing no new-line | |
252 // characters) or that follows white space containing at least one | |
253 // new-line character. The last token in the sequence is the first | |
254 // new-line character that follows the first token in the sequence. | |
255 | |
256 pp_statement | |
257 = ( plain_define | |
258 // | include_file | |
259 // | system_include_file | |
260 | ppif | |
261 | ppelif | |
262 | ppifndef | |
263 | ppifdef | |
264 | undefine | |
265 // | ppelse | |
266 | macro_include_file | |
267 | ppline | |
268 | pppragma | |
269 | pperror | |
270 | ppwarning | |
271 // | ppendif | |
272 #if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0 | |
273 | ppregion | |
274 | ppendregion | |
275 #endif | |
276 | illformed | |
277 ) | |
278 >> eol_tokens | |
279 [ store_found_eoltokens_type(self.found_eoltokens) ] | |
280 // In parser debug mode it is useful not to flush the underlying stream | |
281 // to allow its investigation in the debugger and to see the correct | |
282 // output in the printed debug log.. | |
283 // Note: this may break the parser, though. | |
284 #if !(defined(BOOST_SPIRIT_DEBUG) && \ | |
285 (BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_CPP_GRAMMAR) \ | |
286 ) | |
287 >> impl::flush_underlying_parser_p | |
288 #endif // !(defined(BOOST_SPIRIT_DEBUG) && | |
289 ; | |
290 | |
291 // // #include ... | |
292 // include_file // include "..." | |
293 // = ch_p(T_PP_QHEADER) | |
294 // [ store_found_directive_type(self.found_directive) ] | |
295 // #if BOOST_WAVE_SUPPORT_INCLUDE_NEXT != 0 | |
296 // | ch_p(T_PP_QHEADER_NEXT) | |
297 // [ store_found_directive_type(self.found_directive) ] | |
298 // #endif | |
299 // ; | |
300 | |
301 // system_include_file // include <...> | |
302 // = ch_p(T_PP_HHEADER) | |
303 // [ store_found_directive_type(self.found_directive) ] | |
304 // #if BOOST_WAVE_SUPPORT_INCLUDE_NEXT != 0 | |
305 // | ch_p(T_PP_HHEADER_NEXT) | |
306 // [ store_found_directive_type(self.found_directive) ] | |
307 // #endif | |
308 // ; | |
309 | |
310 macro_include_file // include ...anything else... | |
311 = no_node_d | |
312 [ | |
313 ch_p(T_PP_INCLUDE) | |
314 [ store_found_directive_type(self.found_directive) ] | |
315 #if BOOST_WAVE_SUPPORT_INCLUDE_NEXT != 0 | |
316 | ch_p(T_PP_INCLUDE_NEXT) | |
317 [ store_found_directive_type(self.found_directive) ] | |
318 #endif | |
319 ] | |
320 >> *( anychar_p - | |
321 (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF)) | |
322 ) | |
323 ; | |
324 | |
325 // #define FOO foo (with optional parameters) | |
326 plain_define | |
327 = no_node_d | |
328 [ | |
329 ch_p(T_PP_DEFINE) | |
330 [ store_found_directive_type(self.found_directive) ] | |
331 >> +ppsp | |
332 ] | |
333 >> ( ch_p(T_IDENTIFIER) | |
334 | pattern_p(KeywordTokenType, | |
335 TokenTypeMask|PPTokenFlag) | |
336 | pattern_p(OperatorTokenType|AltExtTokenType, | |
337 ExtTokenTypeMask|PPTokenFlag) // and, bit_and etc. | |
338 | pattern_p(BoolLiteralTokenType, | |
339 TokenTypeMask|PPTokenFlag) // true/false | |
340 ) | |
341 >> ( ( no_node_d[eps_p(ch_p(T_LEFTPAREN))] | |
342 >> macro_parameters | |
343 >> !macro_definition | |
344 ) | |
345 | !( no_node_d[+ppsp] | |
346 >> macro_definition | |
347 ) | |
348 ) | |
349 ; | |
350 | |
351 // parameter list | |
352 // normal C++ mode | |
353 macro_parameters | |
354 = confix_p( | |
355 no_node_d[ch_p(T_LEFTPAREN) >> *ppsp], | |
356 !list_p( | |
357 ( ch_p(T_IDENTIFIER) | |
358 | pattern_p(KeywordTokenType, | |
359 TokenTypeMask|PPTokenFlag) | |
360 | pattern_p(OperatorTokenType|AltExtTokenType, | |
361 ExtTokenTypeMask|PPTokenFlag) // and, bit_and etc. | |
362 | pattern_p(BoolLiteralTokenType, | |
363 TokenTypeMask|PPTokenFlag) // true/false | |
364 #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 | |
365 | ch_p(T_ELLIPSIS) | |
366 #endif | |
367 ), | |
368 no_node_d[*ppsp >> ch_p(T_COMMA) >> *ppsp] | |
369 ), | |
370 no_node_d[*ppsp >> ch_p(T_RIGHTPAREN)] | |
371 ) | |
372 ; | |
373 | |
374 // macro body (anything left until eol) | |
375 macro_definition | |
376 = no_node_d[*ppsp] | |
377 >> *( anychar_p - | |
378 (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF)) | |
379 ) | |
380 ; | |
381 | |
382 // #undef FOO | |
383 undefine | |
384 = no_node_d | |
385 [ | |
386 ch_p(T_PP_UNDEF) | |
387 [ store_found_directive_type(self.found_directive) ] | |
388 >> +ppsp | |
389 ] | |
390 >> ( ch_p(T_IDENTIFIER) | |
391 | pattern_p(KeywordTokenType, | |
392 TokenTypeMask|PPTokenFlag) | |
393 | pattern_p(OperatorTokenType|AltExtTokenType, | |
394 ExtTokenTypeMask|PPTokenFlag) // and, bit_and etc. | |
395 | pattern_p(BoolLiteralTokenType, | |
396 TokenTypeMask|PPTokenFlag) // true/false | |
397 ) | |
398 ; | |
399 | |
400 // #ifdef et.al. | |
401 ppifdef | |
402 = no_node_d | |
403 [ | |
404 ch_p(T_PP_IFDEF) | |
405 [ store_found_directive_type(self.found_directive) ] | |
406 >> +ppsp | |
407 ] | |
408 >> ppqualifiedname | |
409 ; | |
410 | |
411 ppifndef | |
412 = no_node_d | |
413 [ | |
414 ch_p(T_PP_IFNDEF) | |
415 [ store_found_directive_type(self.found_directive) ] | |
416 >> +ppsp | |
417 ] | |
418 >> ppqualifiedname | |
419 ; | |
420 | |
421 ppif | |
422 = no_node_d | |
423 [ | |
424 ch_p(T_PP_IF) | |
425 [ store_found_directive_type(self.found_directive) ] | |
426 // >> *ppsp | |
427 ] | |
428 >> +( anychar_p - | |
429 (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF)) | |
430 ) | |
431 ; | |
432 | |
433 // ppelse | |
434 // = no_node_d | |
435 // [ | |
436 // ch_p(T_PP_ELSE) | |
437 // [ store_found_directive_type(self.found_directive) ] | |
438 // ] | |
439 // ; | |
440 | |
441 ppelif | |
442 = no_node_d | |
443 [ | |
444 ch_p(T_PP_ELIF) | |
445 [ store_found_directive_type(self.found_directive) ] | |
446 // >> *ppsp | |
447 ] | |
448 >> +( anychar_p - | |
449 (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF)) | |
450 ) | |
451 ; | |
452 | |
453 // ppendif | |
454 // = no_node_d | |
455 // [ | |
456 // ch_p(T_PP_ENDIF) | |
457 // [ store_found_directive_type(self.found_directive) ] | |
458 // ] | |
459 // ; | |
460 | |
461 // #line ... | |
462 ppline | |
463 = no_node_d | |
464 [ | |
465 ch_p(T_PP_LINE) | |
466 [ store_found_directive_type(self.found_directive) ] | |
467 >> *ppsp | |
468 ] | |
469 >> +( anychar_p - | |
470 (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF)) | |
471 ) | |
472 ; | |
473 | |
474 #if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0 | |
475 // #region ... | |
476 ppregion | |
477 = no_node_d | |
478 [ | |
479 ch_p(T_MSEXT_PP_REGION) | |
480 [ store_found_directive_type(self.found_directive) ] | |
481 >> +ppsp | |
482 ] | |
483 >> ppqualifiedname | |
484 ; | |
485 | |
486 // #endregion | |
487 ppendregion | |
488 = no_node_d | |
489 [ | |
490 ch_p(T_MSEXT_PP_ENDREGION) | |
491 [ store_found_directive_type(self.found_directive) ] | |
492 ] | |
493 ; | |
494 #endif | |
495 | |
496 // # something else (ill formed preprocessor directive) | |
497 illformed // for error reporting | |
498 = no_node_d | |
499 [ | |
500 pattern_p(T_POUND, MainTokenMask) | |
501 >> *ppsp | |
502 ] | |
503 >> ( anychar_p - | |
504 (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF)) | |
505 ) | |
506 >> no_node_d | |
507 [ | |
508 *( anychar_p - | |
509 (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF)) | |
510 ) | |
511 ] | |
512 ; | |
513 | |
514 // #error | |
515 pperror | |
516 = no_node_d | |
517 [ | |
518 ch_p(T_PP_ERROR) | |
519 [ store_found_directive_type(self.found_directive) ] | |
520 >> *ppsp | |
521 ] | |
522 >> *( anychar_p - | |
523 (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF)) | |
524 ) | |
525 ; | |
526 | |
527 // #warning | |
528 ppwarning | |
529 = no_node_d | |
530 [ | |
531 ch_p(T_PP_WARNING) | |
532 [ store_found_directive_type(self.found_directive) ] | |
533 >> *ppsp | |
534 ] | |
535 >> *( anychar_p - | |
536 (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF)) | |
537 ) | |
538 ; | |
539 | |
540 // #pragma ... | |
541 pppragma | |
542 = no_node_d | |
543 [ | |
544 ch_p(T_PP_PRAGMA) | |
545 [ store_found_directive_type(self.found_directive) ] | |
546 ] | |
547 >> *( anychar_p - | |
548 (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF)) | |
549 ) | |
550 ; | |
551 | |
552 ppqualifiedname | |
553 = no_node_d[*ppsp] | |
554 >> ( ch_p(T_IDENTIFIER) | |
555 | pattern_p(KeywordTokenType, | |
556 TokenTypeMask|PPTokenFlag) | |
557 | pattern_p(OperatorTokenType|AltExtTokenType, | |
558 ExtTokenTypeMask|PPTokenFlag) // and, bit_and etc. | |
559 | pattern_p(BoolLiteralTokenType, | |
560 TokenTypeMask|PPTokenFlag) // true/false | |
561 ) | |
562 ; | |
563 | |
564 // auxiliary helper rules | |
565 ppsp // valid space in a line with a preprocessor directive | |
566 = ch_p(T_SPACE) | ch_p(T_CCOMMENT) | |
567 ; | |
568 | |
569 // end of line tokens | |
570 eol_tokens | |
571 = no_node_d | |
572 [ | |
573 *( ch_p(T_SPACE) | |
574 | ch_p(T_CCOMMENT) | |
575 ) | |
576 >> ( ch_p(T_NEWLINE) | |
577 | ch_p(T_CPPCOMMENT) | |
578 | ch_p(T_EOF) | |
579 [ store_found_eof_type(self.found_eof) ] | |
580 ) | |
581 ] | |
582 ; | |
583 | |
584 BOOST_SPIRIT_DEBUG_TRACE_RULE(pp_statement, TRACE_CPP_GRAMMAR); | |
585 // BOOST_SPIRIT_DEBUG_TRACE_RULE(include_file, TRACE_CPP_GRAMMAR); | |
586 // BOOST_SPIRIT_DEBUG_TRACE_RULE(system_include_file, TRACE_CPP_GRAMMAR); | |
587 BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_include_file, TRACE_CPP_GRAMMAR); | |
588 BOOST_SPIRIT_DEBUG_TRACE_RULE(plain_define, TRACE_CPP_GRAMMAR); | |
589 BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_definition, TRACE_CPP_GRAMMAR); | |
590 BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_parameters, TRACE_CPP_GRAMMAR); | |
591 BOOST_SPIRIT_DEBUG_TRACE_RULE(undefine, TRACE_CPP_GRAMMAR); | |
592 BOOST_SPIRIT_DEBUG_TRACE_RULE(ppifdef, TRACE_CPP_GRAMMAR); | |
593 BOOST_SPIRIT_DEBUG_TRACE_RULE(ppifndef, TRACE_CPP_GRAMMAR); | |
594 BOOST_SPIRIT_DEBUG_TRACE_RULE(ppif, TRACE_CPP_GRAMMAR); | |
595 // BOOST_SPIRIT_DEBUG_TRACE_RULE(ppelse, TRACE_CPP_GRAMMAR); | |
596 // BOOST_SPIRIT_DEBUG_TRACE_RULE(ppelif, TRACE_CPP_GRAMMAR); | |
597 BOOST_SPIRIT_DEBUG_TRACE_RULE(ppendif, TRACE_CPP_GRAMMAR); | |
598 BOOST_SPIRIT_DEBUG_TRACE_RULE(ppline, TRACE_CPP_GRAMMAR); | |
599 BOOST_SPIRIT_DEBUG_TRACE_RULE(pperror, TRACE_CPP_GRAMMAR); | |
600 BOOST_SPIRIT_DEBUG_TRACE_RULE(ppwarning, TRACE_CPP_GRAMMAR); | |
601 BOOST_SPIRIT_DEBUG_TRACE_RULE(illformed, TRACE_CPP_GRAMMAR); | |
602 BOOST_SPIRIT_DEBUG_TRACE_RULE(ppsp, TRACE_CPP_GRAMMAR); | |
603 BOOST_SPIRIT_DEBUG_TRACE_RULE(ppqualifiedname, TRACE_CPP_GRAMMAR); | |
604 #if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0 | |
605 BOOST_SPIRIT_DEBUG_TRACE_RULE(ppregion, TRACE_CPP_GRAMMAR); | |
606 BOOST_SPIRIT_DEBUG_TRACE_RULE(ppendregion, TRACE_CPP_GRAMMAR); | |
607 #endif | |
608 } | |
609 | |
610 // start rule of this grammar | |
611 rule_type const& start() const | |
612 { return pp_statement; } | |
613 }; | |
614 | |
615 bool &found_eof; | |
616 TokenT &found_directive; | |
617 ContainerT &found_eoltokens; | |
618 | |
619 cpp_grammar(bool &found_eof_, TokenT &found_directive_, | |
620 ContainerT &found_eoltokens_) | |
621 : found_eof(found_eof_), | |
622 found_directive(found_directive_), | |
623 found_eoltokens(found_eoltokens_) | |
624 { | |
625 BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this, "cpp_grammar", | |
626 TRACE_CPP_GRAMMAR); | |
627 } | |
628 | |
629 #if BOOST_WAVE_DUMP_PARSE_TREE != 0 | |
630 // helper function and data to get readable names of the rules known to us | |
631 struct map_ruleid_to_name : | |
632 public std::map<boost::spirit::classic::parser_id, std::string> | |
633 { | |
634 typedef std::map<boost::spirit::classic::parser_id, std::string> base_type; | |
635 | |
636 void init_rule_id_to_name_map(cpp_grammar const &self) | |
637 { | |
638 struct { | |
639 int parser_id; | |
640 char const *rule_name; | |
641 } | |
642 init_ruleid_name_map[] = { | |
643 { BOOST_WAVE_PP_STATEMENT_ID, "pp_statement" }, | |
644 // { BOOST_WAVE_INCLUDE_FILE_ID, "include_file" }, | |
645 // { BOOST_WAVE_SYSINCLUDE_FILE_ID, "system_include_file" }, | |
646 { BOOST_WAVE_MACROINCLUDE_FILE_ID, "macro_include_file" }, | |
647 { BOOST_WAVE_PLAIN_DEFINE_ID, "plain_define" }, | |
648 { BOOST_WAVE_MACRO_PARAMETERS_ID, "macro_parameters" }, | |
649 { BOOST_WAVE_MACRO_DEFINITION_ID, "macro_definition" }, | |
650 { BOOST_WAVE_UNDEFINE_ID, "undefine" }, | |
651 { BOOST_WAVE_IFDEF_ID, "ppifdef" }, | |
652 { BOOST_WAVE_IFNDEF_ID, "ppifndef" }, | |
653 { BOOST_WAVE_IF_ID, "ppif" }, | |
654 { BOOST_WAVE_ELIF_ID, "ppelif" }, | |
655 // { BOOST_WAVE_ELSE_ID, "ppelse" }, | |
656 // { BOOST_WAVE_ENDIF_ID, "ppendif" }, | |
657 { BOOST_WAVE_LINE_ID, "ppline" }, | |
658 { BOOST_WAVE_ERROR_ID, "pperror" }, | |
659 { BOOST_WAVE_WARNING_ID, "ppwarning" }, | |
660 { BOOST_WAVE_PRAGMA_ID, "pppragma" }, | |
661 { BOOST_WAVE_ILLFORMED_ID, "illformed" }, | |
662 { BOOST_WAVE_PPSPACE_ID, "ppspace" }, | |
663 { BOOST_WAVE_PPQUALIFIEDNAME_ID, "ppqualifiedname" }, | |
664 #if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0 | |
665 { BOOST_WAVE_REGION_ID, "ppregion" }, | |
666 { BOOST_WAVE_ENDREGION_ID, "ppendregion" }, | |
667 #endif | |
668 { 0 } | |
669 }; | |
670 | |
671 // initialize parser_id to rule_name map | |
672 for (int i = 0; 0 != init_ruleid_name_map[i].parser_id; ++i) | |
673 base_type::insert(base_type::value_type( | |
674 boost::spirit::classic::parser_id(init_ruleid_name_map[i].parser_id), | |
675 std::string(init_ruleid_name_map[i].rule_name)) | |
676 ); | |
677 } | |
678 }; | |
679 mutable map_ruleid_to_name map_rule_id_to_name; | |
680 #endif // WAVE_DUMP_PARSE_TREE != 0 | |
681 }; | |
682 | |
683 /////////////////////////////////////////////////////////////////////////////// | |
684 #undef TRACE_CPP_GRAMMAR | |
685 | |
686 /////////////////////////////////////////////////////////////////////////////// | |
687 // | |
688 // Special parse function generating a parse tree using a given node_factory. | |
689 // | |
690 /////////////////////////////////////////////////////////////////////////////// | |
691 template <typename NodeFactoryT, typename IteratorT, typename ParserT> | |
692 inline boost::spirit::classic::tree_parse_info<IteratorT, NodeFactoryT> | |
693 parsetree_parse(IteratorT const& first_, IteratorT const& last, | |
694 boost::spirit::classic::parser<ParserT> const& p) | |
695 { | |
696 using namespace boost::spirit::classic; | |
697 | |
698 typedef pt_match_policy<IteratorT, NodeFactoryT> pt_match_policy_type; | |
699 typedef scanner_policies<iteration_policy, pt_match_policy_type> | |
700 scanner_policies_type; | |
701 typedef scanner<IteratorT, scanner_policies_type> scanner_type; | |
702 | |
703 scanner_policies_type policies; | |
704 IteratorT first = first_; | |
705 scanner_type scan(first, last, policies); | |
706 tree_match<IteratorT, NodeFactoryT> hit = p.derived().parse(scan); | |
707 return tree_parse_info<IteratorT, NodeFactoryT>( | |
708 first, hit, hit && (first == last), hit.length(), hit.trees); | |
709 } | |
710 | |
711 /////////////////////////////////////////////////////////////////////////////// | |
712 // | |
713 // The following parse function is defined here, to allow the separation of | |
714 // the compilation of the cpp_grammar from the function using it. | |
715 // | |
716 /////////////////////////////////////////////////////////////////////////////// | |
717 | |
718 #if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0 | |
719 #define BOOST_WAVE_GRAMMAR_GEN_INLINE | |
720 #else | |
721 #define BOOST_WAVE_GRAMMAR_GEN_INLINE inline | |
722 #endif | |
723 | |
724 template <typename LexIteratorT, typename TokenContainerT> | |
725 BOOST_WAVE_GRAMMAR_GEN_INLINE | |
726 boost::spirit::classic::tree_parse_info< | |
727 LexIteratorT, | |
728 typename cpp_grammar_gen<LexIteratorT, TokenContainerT>::node_factory_type | |
729 > | |
730 cpp_grammar_gen<LexIteratorT, TokenContainerT>::parse_cpp_grammar ( | |
731 LexIteratorT const &first, LexIteratorT const &last, | |
732 position_type const &act_pos, bool &found_eof, | |
733 token_type &found_directive, token_container_type &found_eoltokens) | |
734 { | |
735 using namespace boost::spirit::classic; | |
736 using namespace boost::wave; | |
737 | |
738 cpp_grammar<token_type, TokenContainerT> g(found_eof, found_directive, found_eoltokens); | |
739 tree_parse_info<LexIteratorT, node_factory_type> hit = | |
740 parsetree_parse<node_factory_type>(first, last, g); | |
741 | |
742 #if BOOST_WAVE_DUMP_PARSE_TREE != 0 | |
743 if (hit.match) { | |
744 tree_to_xml (BOOST_WAVE_DUMP_PARSE_TREE_OUT, hit.trees, "", | |
745 g.map_rule_id_to_name, &token_type::get_token_id, | |
746 &token_type::get_token_value); | |
747 } | |
748 #endif | |
749 | |
750 return hit; | |
751 } | |
752 | |
753 #undef BOOST_WAVE_GRAMMAR_GEN_INLINE | |
754 | |
755 /////////////////////////////////////////////////////////////////////////////// | |
756 } // namespace grammars | |
757 } // namespace wave | |
758 } // namespace boost | |
759 | |
760 // the suffix header occurs after all of the code | |
761 #ifdef BOOST_HAS_ABI_HEADERS | |
762 #include BOOST_ABI_SUFFIX | |
763 #endif | |
764 | |
765 #endif // !defined(CPP_GRAMMAR_HPP_FEAEBC2E_2734_428B_A7CA_85E5A415E23E_INCLUDED) |