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