]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/wave/include/boost/wave/grammars/cpp_grammar.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / wave / include / boost / wave / grammars / cpp_grammar.hpp
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)