]> git.proxmox.com Git - ceph.git/blame - 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
CommitLineData
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
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///////////////////////////////////////////////////////////////////////////////
40namespace boost {
41namespace wave {
42namespace grammars {
43
44namespace 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.
154template <typename TokenT, typename ContainerT>
155struct 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///////////////////////////////////////////////////////////////////////////////
691template <typename NodeFactoryT, typename IteratorT, typename ParserT>
692inline boost::spirit::classic::tree_parse_info<IteratorT, NodeFactoryT>
693parsetree_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
724template <typename LexIteratorT, typename TokenContainerT>
725BOOST_WAVE_GRAMMAR_GEN_INLINE
726boost::spirit::classic::tree_parse_info<
727 LexIteratorT,
728 typename cpp_grammar_gen<LexIteratorT, TokenContainerT>::node_factory_type
729>
730cpp_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)