]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/wave/samples/hannibal/translation_unit_parser.h
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / wave / samples / hannibal / translation_unit_parser.h
1 // Hannibal: partial C++ grammar to parse C++ type information
2 // Copyright (c) 2005-2006 Danny Havenith
3 //
4 // Boost.Wave: A Standard compliant C++ preprocessor
5 // Copyright (c) 2001-2009 Hartmut Kaiser
6 //
7 // http://www.boost.org/
8 //
9 // Distributed under the Boost Software License, Version 1.0. (See accompanying
10 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
11
12 #if !defined(HANNIBAL_TRANSLATION_UNIT_GRAMMAR_H_INCLUDED)
13 #define HANNIBAL_TRANSLATION_UNIT_GRAMMAR_H_INCLUDED
14
15 #include <map>
16
17 #include <boost/assert.hpp>
18 #include <boost/spirit/include/classic_core.hpp>
19 #include <boost/spirit/include/classic_confix.hpp>
20
21 #include <boost/wave/wave_config.hpp>
22 #include <boost/wave/token_ids.hpp>
23 #include <boost/wave/util/pattern_parser.hpp>
24
25 //
26 // If so required, trace every declaration and member-declaration.
27 // This can be a much faster alternative to BOOST_SPIRIT_DEBUG-type of
28 // debugging.
29 //
30 #ifdef HANNIBAL_TRACE_DECLARATIONS
31 struct trace_actor
32 {
33 trace_actor(
34 const char rule_type[],
35 std::ostream &strm
36 )
37 : strm_( strm), rule_type_( rule_type)
38 {
39 // nop
40 }
41
42 template<typename PositionIterator>
43 void operator()(PositionIterator begin, PositionIterator end) const
44 {
45 typedef const boost::wave::cpplexer::lex_token<>::position_type
46 position_type;
47 //typedef pos_iterator_type::token_type::position_type position_type;
48
49 position_type &begin_pos(begin->get_position());
50
51 strm_ << "Parsed " << rule_type_ << std::endl;
52 strm_ << " from: " << begin_pos.get_file()
53 << "(" << begin_pos.get_line() << ")"
54 << std::endl;
55 };
56
57 private:
58 std::ostream &strm_;
59 char const* const rule_type_;
60 };
61
62 #define HANNIBAL_TRACE_ACTION( type) [trace_actor( (type), std::cout)]
63 #else
64 #define HANNIBAL_TRACE_ACTION( type)
65 #endif
66
67 ///////////////////////////////////////////////////////////////////////////////
68 #define HANNIBAL_TRACE_TRANSLATION_UNIT_GRAMMAR \
69 bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_CPP_EXPR_GRAMMAR) \
70 /**/
71
72 ///////////////////////////////////////////////////////////////////////////////
73 // Helper macro to register rules for debugging
74 #if HANNIBAL_DUMP_PARSE_TREE != 0
75 #define HANNIBAL_REGISTER_RULE(r) \
76 BOOST_SPIRIT_DEBUG_NODE(r); \
77 self.declare_rule(r, #r) \
78 /**/
79 #else
80 #define HANNIBAL_REGISTER_RULE(r) \
81 BOOST_SPIRIT_DEBUG_NODE(r) \
82 /**/
83 #endif
84
85 ///////////////////////////////////////////////////////////////////////////////
86 struct dump_actor {
87 template<typename ForwardIterator>
88 void operator()(ForwardIterator begin, ForwardIterator end)
89 {
90 std::cerr << "*** COULD NOT PARSE THE FOLLOWING ***" << std::endl;
91 while (begin != end)
92 {
93 std::cerr << begin->get_value();
94 ++begin;
95 }
96 }
97 } dump_a;
98
99 ///////////////////////////////////////////////////////////////////////////////
100 struct translation_unit_grammar
101 : public boost::spirit::classic::grammar<translation_unit_grammar>
102 {
103 #if HANNIBAL_DUMP_PARSE_TREE != 0
104 //
105 // allow an external map with rule-id -> rule-name mappings.
106 // this map is external so it can be altered by the definition constructor,
107 // which receives a const grammar object.
108 //
109 // Please Note: the lifetime of the rule map should at least extend beyond the
110 // call of the definition constructor...
111 //
112 typedef std::map<boost::spirit::classic::parser_id, std::string>
113 rule_map_type;
114
115 translation_unit_grammar(rule_map_type *rule_map_ptr_ = 0)
116 : rule_map_ptr(rule_map_ptr_)
117 #else
118 translation_unit_grammar()
119 #endif
120 {
121 BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this,
122 "translation_unit_grammar", HANNIBAL_TRACE_TRANSLATION_UNIT_GRAMMAR);
123 }
124
125 template <typename ScannerT>
126 struct definition
127 {
128 // declare non-terminals
129 typedef boost::spirit::classic::rule<ScannerT> rule_type;
130
131 rule_type constant_expression;
132 rule_type logical_or_exp, logical_and_exp;
133 rule_type inclusive_or_exp, exclusive_or_exp, and_exp;
134 rule_type cmp_equality, cmp_relational;
135 rule_type shift_exp;
136 rule_type add_exp, multiply_exp;
137 rule_type unary_exp, primary_exp, constant;
138
139 boost::spirit::classic::subrule<0> const_exp_subrule;
140 boost::spirit::classic::subrule<1> shift_exp_clos;
141
142 rule_type simple_type_name, class_keywords;
143 rule_type storage_class_specifier, cv_qualifier, function_specifier;
144 rule_type access_specifier;
145 rule_type extension_type_decorator;
146 rule_type operator_sym;
147 rule_type class_key;
148 rule_type enumerator;
149 rule_type enumerator_list;
150 rule_type enumerator_definition;
151 rule_type member_declarator;
152 rule_type member_declarator_list;
153 rule_type member_declaration;
154 rule_type constant_initializer;
155 rule_type pure_specifier;
156 rule_type namespace_body;
157 rule_type type_id;
158 rule_type unnamed_namespace_definition;
159 rule_type extension_namespace_definition;
160 rule_type original_namespace_definition;
161 rule_type named_namespace_definition;
162 rule_type namespace_definition;
163 rule_type linkage_specification;
164 rule_type explicit_specialization;
165 rule_type using_directive;
166 rule_type using_declaration;
167 rule_type type_parameter;
168 rule_type template_parameter;
169 rule_type template_parameter_list;
170 rule_type template_declaration;
171 rule_type explicit_instantiation;
172 rule_type qualified_namespace_specifier;
173 rule_type namespace_alias_definition;
174 rule_type expression_list;
175 rule_type initializer_list;
176 rule_type initializer_clause;
177 rule_type initializer;
178 rule_type init_declarator;
179 rule_type init_declarator_list;
180 rule_type asm_definition;
181 rule_type simple_declaration;
182 rule_type block_declaration;
183 rule_type declaration;
184 rule_type declaration_seq;
185 rule_type translation_unit;
186
187 rule_type function_definition, function_definition_helper, declarator;
188 rule_type direct_declarator, parameters_or_array_spec;
189 rule_type abstract_declarator, direct_abstract_declarator;
190 rule_type direct_abstract_declarator_helper;
191 rule_type parameter_declaration_clause, parameter_declaration_list;
192 rule_type parameter_declaration, assignment_expression, decimal_literal;
193 rule_type octal_literal, hexadecimal_literal;
194 rule_type declarator_id, id_expression, qualified_id, unqualified_id;
195 rule_type operator_function_id, conversion_function_id, conversion_type_id;
196 rule_type conversion_declarator, function_body;
197 rule_type compound_statement, ctor_initializer, ptr_operator;
198 rule_type decl_specifier, type_specifier;
199 rule_type type_specifier_seq, cv_qualifier_seq, enum_specifier;
200 rule_type enum_keyword, simple_type_specifier;
201 rule_type class_specifier, member_specification, class_head;
202 rule_type type_name, elaborated_type_specifier, template_argument_list;
203 rule_type template_argument, nested_name_specifier;
204 rule_type class_or_namespace_name, class_name, enum_name, typedef_name;
205 rule_type namespace_name, template_id;
206 rule_type decl_specifier_seq, no_type_decl_specifier;
207 rule_type function_try_block, handler_seq, handler;
208 rule_type exception_specification, template_name;
209 rule_type original_namespace_name, base_specifier;
210 rule_type base_specifier_list, base_clause;
211 rule_type odd_language_extension, mem_initializer_id;
212 rule_type mem_initializer, mem_initializer_list;
213
214
215 rule_type ta_expression_operator;
216 rule_type ta_logical_or_expression;
217 rule_type ta_expression;
218 rule_type ta_conditional_expression;
219 rule_type ta_throw_expression;
220 rule_type ta_assignment_expression;
221 rule_type postfix_expression_helper;
222 rule_type simple_postfix_expression;
223 rule_type pseudo_destructor_name;
224 rule_type direct_new_declarator;
225 rule_type new_declarator;
226 rule_type new_initializer;
227 rule_type new_type_id;
228 rule_type new_placement;
229 rule_type delete_expression;
230 rule_type new_expression;
231 rule_type unary_operator;
232 rule_type postfix_expression;
233 rule_type unary_expression;
234 rule_type expression_operator;
235 rule_type cast_expression;
236 rule_type throw_expression;
237 rule_type assignment_operator;
238 rule_type logical_or_expression;
239 rule_type conditional_expression;
240 rule_type boolean_literal;
241 rule_type string_literal;
242 rule_type floating_literal;
243 rule_type character_literal;
244 rule_type integer_literal;
245 rule_type expression;
246 rule_type literal;
247 rule_type primary_expression;
248
249 //
250 // grammar definition.
251
252 definition(translation_unit_grammar const& self)
253 {
254 using namespace boost::spirit::classic;
255 using namespace boost::wave;
256 using boost::wave::util::pattern_p;
257
258 //
259 // First, a long list of expression rules.
260 //
261 HANNIBAL_REGISTER_RULE( primary_expression);
262 primary_expression
263 = literal
264 | ch_p(T_THIS)
265 | ch_p(T_COLON_COLON) >> ch_p(T_IDENTIFIER)
266 | ch_p(T_COLON_COLON) >> operator_function_id
267 | ch_p(T_COLON_COLON) >> qualified_id
268 | ch_p(T_LEFTPAREN) >> expression >> ch_p(T_RIGHTPAREN)
269 | id_expression
270 ;
271
272 HANNIBAL_REGISTER_RULE( literal);
273 literal
274 = integer_literal
275 | character_literal
276 | floating_literal
277 | string_literal
278 | boolean_literal
279 ;
280
281 HANNIBAL_REGISTER_RULE( integer_literal);
282 integer_literal
283 = pattern_p( IntegerLiteralTokenType, TokenTypeMask)
284 ;
285
286 HANNIBAL_REGISTER_RULE( character_literal);
287 character_literal
288 = pattern_p( CharacterLiteralTokenType, TokenTypeMask)
289 ;
290
291 HANNIBAL_REGISTER_RULE( floating_literal);
292 floating_literal
293 = pattern_p( FloatingLiteralTokenType, TokenTypeMask)
294 ;
295
296 HANNIBAL_REGISTER_RULE( string_literal);
297 string_literal
298 = pattern_p( StringLiteralTokenType, TokenTypeMask)
299 ;
300
301 HANNIBAL_REGISTER_RULE( boolean_literal);
302 boolean_literal
303 = pattern_p( BoolLiteralTokenType, TokenTypeMask)
304 ;
305
306 //
307 // TODO: separate assignment expression into a grammar of it's own
308 //
309 HANNIBAL_REGISTER_RULE( assignment_expression);
310 assignment_expression
311 = conditional_expression
312 | logical_or_expression >> assignment_operator >> assignment_expression
313 | throw_expression
314 ;
315
316 //
317 // Have a separate assignment expression for template arguments.
318 // This is needed, because without it, an expression of the form
319 // template < a, b, c > x;
320 // would not parse, since the 'c > x' part would be taken by the
321 // assignment expression.
322 //
323 // Note that this ta_xxxxx duplication cascades all the way down to
324 // logical_or_expression.
325 // Both the previous example and a declaration of the form
326 // template < a, b, (c > d) > x;
327 // should parse fine now.
328 //
329 //
330 HANNIBAL_REGISTER_RULE( ta_assignment_expression);
331 ta_assignment_expression
332 = ta_conditional_expression
333 | ta_logical_or_expression >> assignment_operator >> ta_assignment_expression
334 | ta_throw_expression
335 ;
336
337 HANNIBAL_REGISTER_RULE( throw_expression);
338 throw_expression
339 = ch_p(T_THROW) >> !assignment_expression
340 ;
341
342 HANNIBAL_REGISTER_RULE( ta_throw_expression);
343 ta_throw_expression
344 = ch_p(T_THROW) >> !ta_assignment_expression
345 ;
346
347 HANNIBAL_REGISTER_RULE( conditional_expression);
348 conditional_expression
349 = logical_or_expression
350 >> !(
351 ch_p(T_QUESTION_MARK)
352 >> expression
353 >> ch_p(T_COLON)
354 >> assignment_expression
355 )
356 ;
357
358 HANNIBAL_REGISTER_RULE( ta_conditional_expression);
359 ta_conditional_expression
360 = ta_logical_or_expression
361 >> !(
362 ch_p(T_QUESTION_MARK)
363 >> ta_expression
364 >> ch_p(T_COLON)
365 >> ta_assignment_expression
366 )
367 ;
368
369 HANNIBAL_REGISTER_RULE( expression);
370 expression
371 = assignment_expression % ch_p(T_COMMA);
372
373 HANNIBAL_REGISTER_RULE( ta_expression);
374 ta_expression
375 = ta_assignment_expression % ch_p(T_COMMA);
376
377 HANNIBAL_REGISTER_RULE( assignment_operator);
378 assignment_operator
379 = pp(T_ASSIGN)
380 | pp(T_ANDASSIGN)
381 | pp(T_ORASSIGN)
382 | pp(T_XORASSIGN)
383 | pp(T_DIVIDEASSIGN)
384 | pp(T_MINUSASSIGN)
385 | pp(T_PERCENTASSIGN)
386 | pp(T_PLUSASSIGN)
387 | pp(T_SHIFTLEFTASSIGN)
388 | pp(T_SHIFTRIGHTASSIGN)
389 | pp(T_STARASSIGN)
390 ;
391
392
393 // we skip quite a few rules here, since we're not interested in operator precedence
394 // just now.
395 HANNIBAL_REGISTER_RULE( logical_or_expression);
396 logical_or_expression
397 = cast_expression % expression_operator
398 ;
399
400 HANNIBAL_REGISTER_RULE( ta_logical_or_expression);
401 ta_logical_or_expression
402 = cast_expression % ta_expression_operator
403 ;
404
405 HANNIBAL_REGISTER_RULE( expression_operator );
406 expression_operator
407 = ta_expression_operator | pp(T_GREATER)
408 ;
409
410 HANNIBAL_REGISTER_RULE( ta_expression_operator );
411 ta_expression_operator
412 = pp(T_OROR)
413 | pp(T_ANDAND)
414 | pp(T_OR)
415 | pp(T_XOR)
416 | pp(T_AND)
417 | pp(T_NOTEQUAL)
418 | pp(T_EQUAL)
419 | pp(T_GREATEREQUAL)
420 | pp(T_LESSEQUAL)
421 | pp(T_LESS)
422 | pp(T_SHIFTLEFT)
423 | pp(T_SHIFTRIGHT)
424 | pp(T_PLUS)
425 | pp(T_MINUS)
426 | pp(T_PERCENT)
427 | pp(T_DIVIDE)
428 | pp(T_STAR)
429 | pp(T_ARROWSTAR)
430 | pp(T_DOTSTAR)
431 ;
432
433 HANNIBAL_REGISTER_RULE( cast_expression);
434 cast_expression
435 = ch_p(T_LEFTPAREN) >> type_id >> ch_p(T_RIGHTPAREN)
436 >> cast_expression
437 | unary_expression
438 ;
439
440 HANNIBAL_REGISTER_RULE( unary_expression);
441 unary_expression
442 = postfix_expression
443 | ch_p(T_PLUSPLUS) >> cast_expression
444 | ch_p(T_MINUSMINUS) >> cast_expression
445 | unary_operator >> cast_expression
446 | ch_p(T_SIZEOF) >> unary_expression
447 | ch_p(T_SIZEOF)
448 >> ch_p(T_LEFTPAREN) >> type_id >> ch_p(T_RIGHTPAREN)
449 | new_expression
450 | delete_expression
451 ;
452
453 HANNIBAL_REGISTER_RULE( unary_operator);
454 unary_operator
455 = ch_p(T_STAR)
456 | pp(T_AND)
457 | pp(T_PLUS)
458 | ch_p(T_MINUS)
459 | ch_p(T_NOT)
460 | pp(T_COMPL)
461 ;
462
463 HANNIBAL_REGISTER_RULE( new_expression);
464 new_expression
465 = !ch_p(T_COLON_COLON) >> ch_p(T_NEW) >> !new_placement
466 >> (
467 new_type_id >> !new_initializer
468 | ch_p(T_LEFTPAREN) >> type_id >> ch_p(T_RIGHTPAREN) >> !new_initializer
469 )
470 ;
471
472 HANNIBAL_REGISTER_RULE( new_placement);
473 new_placement
474 = ch_p(T_LEFTPAREN) >> expression_list >> ch_p(T_RIGHTPAREN)
475 ;
476
477 HANNIBAL_REGISTER_RULE( new_type_id);
478 new_type_id
479 = type_specifier_seq >> !new_declarator
480 ;
481
482 HANNIBAL_REGISTER_RULE( new_declarator);
483 new_declarator
484 = ptr_operator >> !new_declarator
485 | direct_new_declarator
486 ;
487
488 HANNIBAL_REGISTER_RULE( direct_new_declarator);
489 direct_new_declarator
490 = *( pp(T_LEFTBRACKET) >> expression >> pp(T_RIGHTBRACKET) )
491 >> pp(T_LEFTBRACKET) >> constant_expression >> pp(T_RIGHTBRACKET)
492 ;
493
494 HANNIBAL_REGISTER_RULE( new_initializer);
495 new_initializer
496 = ch_p(T_LEFTPAREN) >> !expression_list >> ch_p(T_RIGHTPAREN)
497 ;
498
499 HANNIBAL_REGISTER_RULE( delete_expression);
500 delete_expression
501 = !ch_p(T_COLON_COLON) >> ch_p(T_DELETE) >> cast_expression
502 | !ch_p(T_COLON_COLON) >> ch_p(T_DELETE)
503 >> pp(T_LEFTBRACKET) >> pp(T_RIGHTBRACKET)
504 >> cast_expression
505 ;
506
507 HANNIBAL_REGISTER_RULE( postfix_expression);
508 postfix_expression
509 = simple_postfix_expression >> *postfix_expression_helper
510 ;
511
512 HANNIBAL_REGISTER_RULE( simple_postfix_expression);
513 simple_postfix_expression
514 = primary_expression
515 | simple_type_specifier
516 >> ch_p(T_LEFTPAREN) >> !expression_list >> ch_p(T_RIGHTPAREN)
517 | ch_p(T_DYNAMICCAST)
518 >> ch_p(T_LESS) >> type_id >> ch_p(T_GREATER)
519 >> ch_p(T_LEFTPAREN) >> expression >> ch_p(T_RIGHTPAREN)
520 | ch_p(T_STATICCAST)
521 >> ch_p(T_LESS) >> type_id >> ch_p(T_GREATER)
522 >> ch_p(T_LEFTPAREN) >> expression >> ch_p(T_RIGHTPAREN)
523 | ch_p(T_REINTERPRETCAST)
524 >> ch_p(T_LESS) >> type_id >> ch_p(T_GREATER)
525 >> ch_p(T_LEFTPAREN) >> expression >> ch_p(T_RIGHTPAREN)
526 | ch_p(T_CONSTCAST)
527 >> ch_p(T_LESS) >> type_id >> ch_p(T_GREATER)
528 >> ch_p(T_LEFTPAREN) >> expression >> ch_p(T_RIGHTPAREN)
529 | ch_p(T_TYPEID)
530 >> ch_p(T_LEFTPAREN) >> expression >> ch_p(T_RIGHTPAREN)
531 | ch_p(T_TYPEID)
532 >> ch_p(T_LEFTPAREN) >> type_id >> ch_p(T_RIGHTPAREN)
533 ;
534
535 HANNIBAL_REGISTER_RULE( postfix_expression_helper );
536 postfix_expression_helper
537 = pp(T_LEFTBRACKET) >> expression >> pp(T_RIGHTBRACKET)
538 | ch_p(T_LEFTPAREN) >> !expression_list >> ch_p(T_RIGHTPAREN)
539 | ch_p(T_DOT) >> !ch_p(T_TEMPLATE) >> !ch_p(T_COLON_COLON) >> id_expression
540 | ch_p(T_ARROW) >> !ch_p(T_TEMPLATE) >> !ch_p(T_COLON_COLON) >> id_expression
541 | ch_p(T_DOT) >> pseudo_destructor_name
542 | ch_p(T_ARROW) >> pseudo_destructor_name
543 | ch_p(T_PLUSPLUS)
544 | ch_p(T_MINUSMINUS)
545 ;
546
547 HANNIBAL_REGISTER_RULE( pseudo_destructor_name);
548 pseudo_destructor_name
549 = !ch_p(T_COLON_COLON) >> !nested_name_specifier
550 >> (
551 type_name >> ch_p(T_COLON_COLON) >> ch_p(T_COMPL) >> type_name
552 | ch_p(T_COMPL) >> type_name
553 )
554 ;
555
556
557 HANNIBAL_REGISTER_RULE(constant_expression);
558 constant_expression
559 = conditional_expression
560 ;
561
562 HANNIBAL_REGISTER_RULE(ctor_initializer);
563 ctor_initializer
564 = ch_p(T_COLON) >> mem_initializer_list
565 ;
566
567 HANNIBAL_REGISTER_RULE(mem_initializer_list);
568 mem_initializer_list
569 = mem_initializer % ch_p(T_COMMA)
570 ;
571
572 HANNIBAL_REGISTER_RULE(mem_initializer);
573 mem_initializer
574 = mem_initializer_id
575 >> comment_nest_p(ch_p(T_LEFTPAREN), ch_p(T_RIGHTPAREN))
576 // TODO: restore after assignment expression has been implemented
577 //ch_p(T_LEFTPAREN) >> !expression_list >> ch_p(T_RIGHTPAREN)
578 ;
579
580 HANNIBAL_REGISTER_RULE(mem_initializer_id);
581 mem_initializer_id
582 = !ch_p(T_COLON_COLON) >> !nested_name_specifier >> class_name
583 | ch_p(T_IDENTIFIER)
584 ;
585
586 //
587 // the eps_p is added to allow skipping of trailing whitespace
588 // (post-skip)
589 //
590 HANNIBAL_REGISTER_RULE(translation_unit);
591 translation_unit
592 = !declaration_seq >> end_p;
593 ;
594
595 HANNIBAL_REGISTER_RULE(odd_language_extension);
596 odd_language_extension // read: microsoft extensions
597 = extension_type_decorator
598 >> !comment_nest_p(ch_p(T_LEFTPAREN), ch_p(T_RIGHTPAREN))
599 ;
600
601 HANNIBAL_REGISTER_RULE(declaration_seq);
602 declaration_seq
603 = +declaration HANNIBAL_TRACE_ACTION( "declaration")
604 ;
605
606 HANNIBAL_REGISTER_RULE(declaration);
607 declaration
608 = template_declaration
609 | explicit_instantiation
610 | explicit_specialization
611 | linkage_specification
612 | namespace_definition
613 | block_declaration
614 | function_definition
615 ;
616
617 HANNIBAL_REGISTER_RULE(block_declaration);
618 block_declaration
619 = simple_declaration
620 | asm_definition
621 | namespace_alias_definition
622 | using_declaration
623 | using_directive
624 ;
625
626 HANNIBAL_REGISTER_RULE(simple_declaration);
627 simple_declaration
628 = !decl_specifier_seq >> !init_declarator_list
629 >> ch_p(T_SEMICOLON)
630 ;
631
632 HANNIBAL_REGISTER_RULE(asm_definition);
633 asm_definition
634 = ch_p(T_ASM)
635 >> ch_p(T_LEFTPAREN) >> ch_p(T_STRINGLIT) >> ch_p(T_RIGHTPAREN)
636 >> ch_p(T_SEMICOLON)
637 ;
638
639 HANNIBAL_REGISTER_RULE(init_declarator_list);
640 init_declarator_list
641 = init_declarator % ch_p(T_COMMA)
642 ;
643
644 HANNIBAL_REGISTER_RULE(init_declarator);
645 init_declarator
646 = declarator >> !initializer
647 ;
648
649 HANNIBAL_REGISTER_RULE(initializer);
650 initializer
651 = ch_p(T_ASSIGN) >> initializer_clause
652 | ch_p(T_LEFTPAREN) >> expression_list >> ch_p(T_RIGHTPAREN)
653 ;
654
655 HANNIBAL_REGISTER_RULE(initializer_clause);
656 initializer_clause
657 = assignment_expression
658 | ch_p(T_LEFTBRACE) >> initializer_list
659 >> !ch_p(T_COMMA) >> ch_p(T_RIGHTBRACE)
660 | ch_p(T_LEFTBRACE) >> ch_p(T_RIGHTBRACE)
661 ;
662
663 HANNIBAL_REGISTER_RULE(initializer_list);
664 initializer_list
665 = initializer_clause % ch_p(T_COMMA)
666 ;
667
668 HANNIBAL_REGISTER_RULE(expression_list);
669 expression_list
670 = assignment_expression % ch_p(T_COMMA)
671 ;
672
673 HANNIBAL_REGISTER_RULE(namespace_alias_definition);
674 namespace_alias_definition
675 = ch_p(T_NAMESPACE) >> ch_p(T_IDENTIFIER) >> ch_p(T_ASSIGN)
676 >> qualified_namespace_specifier
677 >> ch_p(T_SEMICOLON)
678 ;
679
680 HANNIBAL_REGISTER_RULE(qualified_namespace_specifier);
681 qualified_namespace_specifier
682 = !ch_p(T_COLON_COLON) >> !nested_name_specifier
683 >> namespace_name
684 ;
685
686 HANNIBAL_REGISTER_RULE(explicit_instantiation);
687 explicit_instantiation
688 = template_declaration
689 ;
690
691 HANNIBAL_REGISTER_RULE(template_declaration);
692 template_declaration
693 = !ch_p(T_EXPORT) >> ch_p(T_TEMPLATE)
694 >> ch_p(T_LESS) >> template_parameter_list >> ch_p(T_GREATER)
695 >> declaration
696 ;
697
698 HANNIBAL_REGISTER_RULE(template_parameter_list);
699 template_parameter_list
700 = template_parameter % ch_p(T_COMMA)
701 ;
702
703 HANNIBAL_REGISTER_RULE(template_parameter);
704 template_parameter
705 = type_parameter
706 | parameter_declaration
707 ;
708
709 HANNIBAL_REGISTER_RULE(type_parameter);
710 type_parameter
711 = ch_p(T_CLASS) >> !ch_p(T_IDENTIFIER)
712 >> !(ch_p(T_ASSIGN) >> type_id)
713 | ch_p(T_TYPENAME) >> !ch_p(T_IDENTIFIER)
714 >> !(ch_p(T_ASSIGN) >> type_id)
715 | ch_p(T_TEMPLATE)
716 >> ch_p(T_LESS) >> template_parameter_list >> ch_p(T_GREATER)
717 >> ch_p(T_CLASS) >> !ch_p(T_IDENTIFIER)
718 >> !(ch_p(T_ASSIGN) >> template_name)
719 ;
720
721 HANNIBAL_REGISTER_RULE(template_name);
722 template_name
723 = ch_p(T_IDENTIFIER)
724 ;
725
726 HANNIBAL_REGISTER_RULE(using_declaration);
727 using_declaration // optimize?
728 = ch_p(T_USING) >> !ch_p(T_TYPENAME) >> !ch_p(T_COLON_COLON)
729 >> nested_name_specifier >> unqualified_id
730 >> ch_p(T_SEMICOLON)
731 | ch_p(T_USING) >> ch_p(T_COLON_COLON) >> unqualified_id
732 >> ch_p(T_SEMICOLON)
733 ;
734
735 HANNIBAL_REGISTER_RULE(using_directive);
736 using_directive
737 = ch_p(T_USING) >> ch_p(T_NAMESPACE) >> !ch_p(T_COLON_COLON)
738 >> !nested_name_specifier >> namespace_name
739 >> ch_p(T_SEMICOLON)
740 ;
741
742 HANNIBAL_REGISTER_RULE(explicit_specialization);
743 explicit_specialization
744 = ch_p(T_TEMPLATE) >> ch_p(T_LESS) >> ch_p(T_GREATER)
745 >> declaration
746 ;
747
748 HANNIBAL_REGISTER_RULE(linkage_specification);
749 linkage_specification
750 = ch_p(T_EXTERN) >> ch_p(T_STRINGLIT)
751 >> ( ch_p(T_LEFTBRACE) >> !declaration_seq >> ch_p(T_RIGHTBRACE)
752 | declaration
753 )
754 ;
755
756 HANNIBAL_REGISTER_RULE(namespace_definition);
757 namespace_definition
758 = named_namespace_definition
759 | unnamed_namespace_definition // TODO: optimize?
760 ;
761
762 HANNIBAL_REGISTER_RULE(named_namespace_definition);
763 named_namespace_definition
764 = original_namespace_definition
765 // | extension_namespace_definition // optimization: extension namespace is syntactically identical
766 ;
767
768 HANNIBAL_REGISTER_RULE(original_namespace_definition);
769 original_namespace_definition
770 = ch_p(T_NAMESPACE) >> ch_p(T_IDENTIFIER)
771 >> ch_p(T_LEFTBRACE) >> namespace_body >> ch_p(T_RIGHTBRACE)
772 ;
773
774 HANNIBAL_REGISTER_RULE(extension_namespace_definition);
775 extension_namespace_definition
776 = ch_p(T_NAMESPACE) >> original_namespace_name
777 >> ch_p(T_LEFTBRACE) >> namespace_body >> ch_p(T_RIGHTBRACE)
778 ;
779
780 HANNIBAL_REGISTER_RULE(original_namespace_name);
781 original_namespace_name
782 = ch_p(T_IDENTIFIER)
783 ;
784
785 HANNIBAL_REGISTER_RULE(unnamed_namespace_definition);
786 unnamed_namespace_definition
787 = ch_p(T_NAMESPACE)
788 >> ch_p(T_LEFTBRACE) >> namespace_body >> ch_p(T_RIGHTBRACE)
789 ;
790
791 HANNIBAL_REGISTER_RULE(namespace_body);
792 namespace_body
793 = !declaration_seq
794 ;
795
796 HANNIBAL_REGISTER_RULE(function_definition);
797 function_definition
798 = function_definition_helper
799 >> !ctor_initializer >> !function_body // removed semicolons
800 | decl_specifier_seq >> declarator >> function_try_block
801 | declarator >> function_try_block
802 ;
803
804 HANNIBAL_REGISTER_RULE(function_definition_helper);
805 function_definition_helper
806 = decl_specifier_seq >> declarator
807 | +no_type_decl_specifier >> declarator
808 | declarator
809 ;
810
811 HANNIBAL_REGISTER_RULE(function_try_block);
812 function_try_block
813 = ch_p(T_TRY)
814 >> !ctor_initializer >> function_body >> handler_seq
815 ;
816
817 HANNIBAL_REGISTER_RULE(handler_seq);
818 handler_seq
819 = +handler
820 ;
821
822 HANNIBAL_REGISTER_RULE(handler);
823 handler // TODO
824 = ch_p(T_CATCH)
825 >> comment_nest_p(ch_p(T_LEFTPAREN), ch_p(T_RIGHTPAREN))
826 >> compound_statement
827 ;
828
829 HANNIBAL_REGISTER_RULE(declarator);
830 declarator
831 = *( ptr_operator
832 | odd_language_extension
833 )
834 >> direct_declarator
835 ;
836
837 HANNIBAL_REGISTER_RULE(direct_declarator);
838 direct_declarator
839 = ( declarator_id
840 | ch_p(T_LEFTPAREN) >> declarator >> ch_p(T_RIGHTPAREN)
841 )
842 >> *parameters_or_array_spec
843 ;
844
845 HANNIBAL_REGISTER_RULE(parameters_or_array_spec);
846 parameters_or_array_spec
847 = ch_p(T_LEFTPAREN) >> parameter_declaration_clause >> ch_p(T_RIGHTPAREN)
848 >> !cv_qualifier_seq >> !exception_specification
849 | pp(T_LEFTBRACKET) >> !constant_expression >> pp(T_RIGHTBRACKET)
850 ;
851
852 HANNIBAL_REGISTER_RULE(exception_specification);
853 exception_specification // TODO
854 = ch_p(T_THROW)
855 >> comment_nest_p(ch_p(T_LEFTPAREN), ch_p(T_RIGHTPAREN))
856 ;
857
858 HANNIBAL_REGISTER_RULE(abstract_declarator);
859 abstract_declarator
860 = +( ptr_operator
861 | odd_language_extension
862 )
863 >> !direct_abstract_declarator
864 | direct_abstract_declarator
865 ;
866
867 HANNIBAL_REGISTER_RULE(direct_abstract_declarator);
868 direct_abstract_declarator
869 = ch_p(T_LEFTPAREN) >> abstract_declarator >> ch_p(T_RIGHTPAREN)
870 >> *direct_abstract_declarator_helper
871 ;
872
873 HANNIBAL_REGISTER_RULE(direct_abstract_declarator_helper);
874 direct_abstract_declarator_helper
875 = ch_p(T_LEFTPAREN) >> parameter_declaration_clause >> ch_p(T_RIGHTPAREN)
876 >> !cv_qualifier_seq >> !exception_specification
877 | pp(T_LEFTBRACKET) >> !constant_expression >> pp(T_RIGHTBRACKET)
878 ;
879
880 HANNIBAL_REGISTER_RULE(parameter_declaration_clause);
881 parameter_declaration_clause
882 = parameter_declaration_list >> ch_p(T_COMMA)
883 >> ch_p(T_ELLIPSIS)
884 | !parameter_declaration_list >> !ch_p(T_ELLIPSIS)
885 ;
886
887 HANNIBAL_REGISTER_RULE(parameter_declaration_list);
888 parameter_declaration_list
889 = parameter_declaration % ch_p(T_COMMA)
890 ;
891
892
893 HANNIBAL_REGISTER_RULE(parameter_declaration);
894 parameter_declaration
895 = decl_specifier_seq
896 >> !(declarator | abstract_declarator)
897 >> !(ch_p(T_ASSIGN) >> assignment_expression)
898 ;
899
900 HANNIBAL_REGISTER_RULE(declarator_id);
901 declarator_id
902 = !ch_p(T_COLON_COLON)
903 >> ( id_expression
904 | !nested_name_specifier >> type_name
905 )
906 ;
907
908 HANNIBAL_REGISTER_RULE(id_expression);
909 id_expression
910 = qualified_id
911 | unqualified_id
912 ;
913
914 HANNIBAL_REGISTER_RULE(qualified_id);
915 qualified_id
916 = nested_name_specifier >> !ch_p(T_TEMPLATE) >> unqualified_id
917 ;
918
919 HANNIBAL_REGISTER_RULE(unqualified_id);
920 unqualified_id
921 = operator_function_id
922 | conversion_function_id
923 | ch_p(T_COMPL) >> class_name
924 | template_id
925 | ch_p(T_IDENTIFIER)
926 ;
927
928 HANNIBAL_REGISTER_RULE(operator_function_id);
929 operator_function_id
930 = ch_p(T_OPERATOR) >> operator_sym // this is called 'operator' in the std grammar
931 ;
932
933 HANNIBAL_REGISTER_RULE(operator_sym);
934 operator_sym
935 = ch_p(T_DELETE) >> !(pp(T_LEFTBRACKET) >> pp(T_RIGHTBRACKET))
936 | ch_p(T_NEW) >> !(pp(T_LEFTBRACKET) >> pp(T_RIGHTBRACKET))
937 | pp(T_LEFTBRACKET) >> pp(T_RIGHTBRACKET)
938 | ch_p(T_LEFTPAREN) >> ch_p(T_RIGHTPAREN)
939 | pattern_p(OperatorTokenType, TokenTypeMask)
940 ;
941
942 HANNIBAL_REGISTER_RULE(conversion_function_id);
943 conversion_function_id
944 = ch_p(T_OPERATOR) >> conversion_type_id
945 ;
946
947 HANNIBAL_REGISTER_RULE( conversion_type_id);
948 conversion_type_id
949 = type_specifier_seq >> !conversion_declarator
950 ;
951
952 HANNIBAL_REGISTER_RULE(type_id);
953 type_id
954 = type_specifier_seq >> !abstract_declarator
955 ;
956
957
958 HANNIBAL_REGISTER_RULE(conversion_declarator);
959 conversion_declarator
960 = ptr_operator >> !conversion_declarator
961 ;
962
963 HANNIBAL_REGISTER_RULE(function_body);
964 function_body
965 = compound_statement
966 ;
967
968 HANNIBAL_REGISTER_RULE(compound_statement);
969 compound_statement
970 = comment_nest_p(ch_p(T_LEFTBRACE), ch_p(T_RIGHTBRACE))
971 ; // TODO later
972
973
974 HANNIBAL_REGISTER_RULE(ptr_operator);
975 ptr_operator
976 = ch_p(T_STAR) >> !cv_qualifier_seq
977 | ch_p(T_AND)
978 | !ch_p(T_COLON_COLON) >> nested_name_specifier
979 >> ch_p(T_STAR) >> !cv_qualifier_seq
980 ;
981
982
983 HANNIBAL_REGISTER_RULE(decl_specifier);
984 decl_specifier
985 = no_type_decl_specifier
986 | type_specifier
987 ;
988
989 HANNIBAL_REGISTER_RULE(no_type_decl_specifier);
990 no_type_decl_specifier
991 = storage_class_specifier
992 | function_specifier
993 | ch_p(T_FRIEND)
994 | ch_p(T_TYPEDEF)
995 | cv_qualifier
996 | odd_language_extension
997 ;
998
999 HANNIBAL_REGISTER_RULE(type_specifier_seq);
1000 type_specifier_seq
1001 = +type_specifier
1002 ;
1003
1004 HANNIBAL_REGISTER_RULE(type_specifier);
1005 type_specifier
1006 = enum_specifier
1007 | class_specifier
1008 | elaborated_type_specifier
1009 | simple_type_specifier
1010 | cv_qualifier
1011 ;
1012
1013 HANNIBAL_REGISTER_RULE(cv_qualifier_seq);
1014 cv_qualifier_seq
1015 = cv_qualifier >> !cv_qualifier_seq
1016 ;
1017
1018 HANNIBAL_REGISTER_RULE(cv_qualifier);
1019 cv_qualifier
1020 = ch_p(T_CONST)
1021 | ch_p(T_VOLATILE)
1022 ;
1023
1024 HANNIBAL_REGISTER_RULE(enum_specifier);
1025 enum_specifier
1026 = enum_keyword >> !ch_p(T_IDENTIFIER)
1027 >> ch_p(T_LEFTBRACE) >> !enumerator_list >> ch_p(T_RIGHTBRACE)
1028 ;
1029
1030 HANNIBAL_REGISTER_RULE(enum_keyword);
1031 enum_keyword
1032 = ch_p(T_ENUM)
1033 ;
1034
1035 HANNIBAL_REGISTER_RULE(enumerator_list);
1036 enumerator_list
1037 = enumerator_definition % ch_p(T_COMMA)
1038 >> !ch_p(T_COMMA)
1039 // TODO find out if this last COMMA_T is an MS-"extension"?
1040 // it seems not to be in the grammar but MSVC 7.0 accepts it.
1041 ;
1042
1043 HANNIBAL_REGISTER_RULE(enumerator_definition);
1044 enumerator_definition
1045 = enumerator >> !(ch_p(T_ASSIGN) >> constant_expression)
1046 ;
1047
1048 HANNIBAL_REGISTER_RULE(enumerator);
1049 enumerator
1050 = ch_p(T_IDENTIFIER)
1051 ;
1052
1053
1054 HANNIBAL_REGISTER_RULE(simple_type_specifier);
1055 simple_type_specifier
1056 = !ch_p(T_COLON_COLON) >> !nested_name_specifier
1057 >> ch_p(T_TEMPLATE) >> template_id
1058 | +simple_type_name
1059 | !ch_p(T_COLON_COLON) >> !nested_name_specifier >> type_name
1060 ;
1061
1062 HANNIBAL_REGISTER_RULE(class_head);
1063 class_head // DH changed the order because otherwise it would always parse the (!IDENTIFIER) part.
1064 = !access_specifier >> *odd_language_extension
1065 >> class_key >> *odd_language_extension
1066 >> (
1067 !nested_name_specifier >> template_id
1068 | nested_name_specifier >> ch_p(T_IDENTIFIER)
1069 | !ch_p(T_IDENTIFIER)
1070 )
1071 >> !base_clause
1072 ;
1073
1074 HANNIBAL_REGISTER_RULE(type_name);
1075 type_name
1076 = class_name
1077 | enum_name
1078 | typedef_name
1079 ;
1080
1081 HANNIBAL_REGISTER_RULE(elaborated_type_specifier);
1082 elaborated_type_specifier
1083 = class_key >> *odd_language_extension
1084 >> !ch_p(T_COLON_COLON)
1085 >> !nested_name_specifier
1086 >> (
1087 !ch_p(T_TEMPLATE) >> template_id
1088 | ch_p(T_IDENTIFIER)
1089 )
1090 | ch_p(T_ENUM) >> !ch_p(T_COLON_COLON)
1091 >> !nested_name_specifier
1092 >> ch_p(T_IDENTIFIER)
1093 | ch_p(T_TYPENAME)
1094 >> !ch_p(T_COLON_COLON)
1095 >> nested_name_specifier
1096 >> (
1097 !ch_p(T_TEMPLATE) >> template_id
1098 | ch_p(T_IDENTIFIER)
1099 )
1100 ;
1101
1102 HANNIBAL_REGISTER_RULE(template_argument_list);
1103 template_argument_list
1104 = template_argument % ch_p(T_COMMA)
1105 ;
1106
1107 HANNIBAL_REGISTER_RULE(template_argument);
1108 template_argument
1109 = longest_d
1110 [
1111 type_id
1112 | ta_assignment_expression
1113 | template_name
1114 ]
1115 ;
1116
1117 HANNIBAL_REGISTER_RULE(class_key);
1118 class_key
1119 = class_keywords
1120 ;
1121
1122 HANNIBAL_REGISTER_RULE(class_keywords);
1123 class_keywords
1124 = ch_p(T_CLASS)
1125 | ch_p(T_STRUCT)
1126 | ch_p(T_UNION)
1127 ;
1128
1129 HANNIBAL_REGISTER_RULE(nested_name_specifier);
1130 nested_name_specifier
1131 = class_or_namespace_name >> ch_p(T_COLON_COLON)
1132 >> ch_p(T_TEMPLATE) >> nested_name_specifier
1133 | class_or_namespace_name >> ch_p(T_COLON_COLON)
1134 >> !nested_name_specifier
1135 ;
1136
1137 HANNIBAL_REGISTER_RULE(class_or_namespace_name);
1138 class_or_namespace_name
1139 = class_name
1140 | namespace_name
1141 ;
1142
1143 HANNIBAL_REGISTER_RULE(class_name);
1144 class_name
1145 = template_id
1146 | ch_p(T_IDENTIFIER)
1147 ;
1148
1149 HANNIBAL_REGISTER_RULE(enum_name);
1150 enum_name
1151 = ch_p(T_IDENTIFIER)
1152 ;
1153
1154 HANNIBAL_REGISTER_RULE(typedef_name);
1155 typedef_name
1156 = ch_p(T_IDENTIFIER)
1157 ;
1158
1159 HANNIBAL_REGISTER_RULE(namespace_name);
1160 namespace_name // TODO
1161 = ch_p(T_IDENTIFIER)
1162 ;
1163
1164 HANNIBAL_REGISTER_RULE(template_id);
1165 template_id
1166 = template_name
1167 >> ch_p(T_LESS) >> template_argument_list >> ch_p(T_GREATER)
1168 ;
1169
1170 //
1171 // This is kind of a HACK. We want to prevent the decl_specifier_seq
1172 // from eating the whole declaration, including the ch_p(T_IDENTIFIER).
1173 // Therefore in the sequence, we only allow one 'unknown' word
1174 // (the type_specifier), the rest of the decl_specifier sequence
1175 // must consist of known keywords or constructs (the
1176 // no_type_decl_specifier).
1177 // This means that a declaration like:
1178 // MYDLL_EXPORT int f();
1179 // will not be accepted unless the MYDLL_EXPORT is properly
1180 // expanded by the preprocessor first.
1181 //
1182 // This should not cause any problems normally, it just means that
1183 // this rule is not very robust in the case where not all symbols
1184 // are known.
1185 //
1186 HANNIBAL_REGISTER_RULE(decl_specifier_seq);
1187 decl_specifier_seq
1188 = *no_type_decl_specifier >> type_specifier >> *no_type_decl_specifier
1189 ;
1190
1191 // The following rule is more according to the standard grammar
1192 // decl_specifier_seq // adapted
1193 // = decl_specifier >> decl_specifier_seq
1194 // | (decl_specifier - (declarator_id >> parameters_or_array_spec ))
1195 // ;
1196
1197 HANNIBAL_REGISTER_RULE( storage_class_specifier);
1198 storage_class_specifier
1199 = ch_p(T_AUTO)
1200 | ch_p(T_REGISTER)
1201 | ch_p(T_STATIC)
1202 | ch_p(T_EXTERN)
1203 | ch_p(T_MUTABLE)
1204 ;
1205
1206 HANNIBAL_REGISTER_RULE( function_specifier);
1207 function_specifier
1208 = ch_p(T_INLINE)
1209 | ch_p(T_VIRTUAL)
1210 | ch_p(T_EXPLICIT)
1211 ;
1212
1213 HANNIBAL_REGISTER_RULE(class_specifier);
1214 class_specifier
1215 = class_head
1216 >> ch_p(T_LEFTBRACE) >> !member_specification >> ch_p(T_RIGHTBRACE)
1217 ;
1218
1219 HANNIBAL_REGISTER_RULE(member_specification);
1220 member_specification
1221 = +( access_specifier >> ch_p(T_COLON)
1222 | member_declaration HANNIBAL_TRACE_ACTION("member declaration")
1223 )
1224 ;
1225
1226 // member_specification
1227 // = access_specifier >> COLON_T >> !member_specification
1228 // | member_declaration >> !member_specification
1229 // ;
1230
1231 HANNIBAL_REGISTER_RULE(member_declaration);
1232 member_declaration
1233 = using_declaration
1234 | template_declaration
1235 | !decl_specifier_seq >> !member_declarator_list
1236 >> ch_p(T_SEMICOLON)
1237 | function_definition >>
1238 !ch_p(T_SEMICOLON)
1239 | qualified_id
1240 >> ch_p(T_SEMICOLON)
1241 ;
1242
1243 HANNIBAL_REGISTER_RULE(member_declarator_list);
1244 member_declarator_list
1245 = member_declarator % ch_p(T_COMMA)
1246 ;
1247
1248 HANNIBAL_REGISTER_RULE(member_declarator);
1249 member_declarator
1250 = !ch_p(T_IDENTIFIER) >> ch_p(T_COLON) >> constant_expression
1251 | declarator >> !(pure_specifier | constant_initializer)
1252 ;
1253
1254 HANNIBAL_REGISTER_RULE(pure_specifier);
1255 pure_specifier
1256 = ch_p(T_ASSIGN) >> ch_p(T_INTLIT)
1257 ;
1258
1259 HANNIBAL_REGISTER_RULE(constant_initializer);
1260 constant_initializer
1261 = ch_p(T_ASSIGN) >> constant_expression
1262 ;
1263
1264 HANNIBAL_REGISTER_RULE(access_specifier);
1265 access_specifier
1266 = ch_p(T_PUBLIC)
1267 | ch_p(T_PROTECTED)
1268 | ch_p(T_PRIVATE)
1269 ;
1270
1271 HANNIBAL_REGISTER_RULE(base_clause);
1272 base_clause
1273 = ch_p(T_COLON) >> base_specifier_list
1274 ;
1275
1276 HANNIBAL_REGISTER_RULE(base_specifier_list);
1277 base_specifier_list
1278 = base_specifier % ch_p(T_COMMA)
1279 ;
1280
1281 HANNIBAL_REGISTER_RULE(base_specifier);
1282 base_specifier
1283 = ch_p(T_VIRTUAL) >> !access_specifier >> !ch_p(T_COLON_COLON)
1284 >> !nested_name_specifier >> class_name
1285 | access_specifier >> !ch_p(T_VIRTUAL) >> !ch_p(T_COLON_COLON)
1286 >> !nested_name_specifier >> class_name
1287 | !ch_p(T_COLON_COLON) >> !nested_name_specifier >> class_name
1288 ;
1289
1290 HANNIBAL_REGISTER_RULE(extension_type_decorator);
1291 extension_type_decorator
1292 = ch_p(T_MSEXT_CDECL)
1293 | ch_p(T_MSEXT_DECLSPEC)
1294 | ch_p(T_MSEXT_BASED)
1295 | ch_p(T_MSEXT_FASTCALL)
1296 | ch_p(T_MSEXT_INLINE)
1297 ;
1298
1299 HANNIBAL_REGISTER_RULE(simple_type_name);
1300 simple_type_name
1301 = ch_p(T_CHAR)
1302 | ch_p(T_WCHART)
1303 | ch_p(T_BOOL)
1304 | ch_p(T_SHORT)
1305 | ch_p(T_INT)
1306 | ch_p(T_LONG)
1307 | ch_p(T_UNSIGNED)
1308 | ch_p(T_SIGNED)
1309 | ch_p(T_FLOAT)
1310 | ch_p(T_DOUBLE)
1311 | ch_p(T_VOID)
1312 | ch_p(T_MSEXT_INT64)
1313 | ch_p(T_MSEXT_INT8)
1314 | ch_p(T_MSEXT_INT16)
1315 | ch_p(T_MSEXT_INT32)
1316 ;
1317 }
1318
1319 rule_type const& start() const { return translation_unit; }
1320
1321 // Helper function wrapping pattern_p
1322 static inline boost::wave::util::pattern_and< boost::wave::token_id>
1323 pp (boost::wave::token_id id)
1324 {
1325 using namespace boost::wave;
1326 return util::pattern_p(id, MainTokenMask);
1327 }
1328 };
1329
1330 #if HANNIBAL_DUMP_PARSE_TREE != 0
1331 private:
1332 template<typename Rule>
1333 void declare_rule(Rule const& rule, std::string const& rule_name) const
1334 {
1335 if (rule_map_ptr)
1336 (*rule_map_ptr)[rule.id()] = rule_name;
1337 }
1338 rule_map_type *rule_map_ptr;
1339 #endif
1340 };
1341
1342 #undef HANNIBAL_REGISTER_RULE
1343 #undef HANNIBAL_TRACE_TRANSLATION_UNIT_GRAMMAR
1344
1345 #endif // HANNIBAL_TRANSLATION_UNIT_GRAMMAR_H_INCLUDED