1 // Hannibal: partial C++ grammar to parse C++ type information
2 // Copyright (c) 2005-2006 Danny Havenith
4 // Boost.Wave: A Standard compliant C++ preprocessor
5 // Copyright (c) 2001-2009 Hartmut Kaiser
7 // http://www.boost.org/
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)
12 #if !defined(BOOST_HANNIBAL_TRANSLATION_UNIT_GRAMMAR_H_INCLUDED)
13 #define BOOST_HANNIBAL_TRANSLATION_UNIT_GRAMMAR_H_INCLUDED
16 #if defined(HANNIBAL_TRACE_DECLARATIONS)
20 #include <boost/assert.hpp>
21 #include <boost/spirit/include/classic_core.hpp>
22 #include <boost/spirit/include/classic_confix.hpp>
24 #include <boost/wave/wave_config.hpp>
25 #include <boost/wave/token_ids.hpp>
26 #include <boost/wave/util/pattern_parser.hpp>
29 // If so required, trace every declaration and member-declaration.
30 // This can be a much faster alternative to BOOST_SPIRIT_DEBUG-type of
33 #ifdef HANNIBAL_TRACE_DECLARATIONS
37 const char rule_type
[],
40 : strm_( strm
), rule_type_( rule_type
)
45 template<typename PositionIterator
>
46 void operator()(PositionIterator begin
, PositionIterator end
) const
48 typedef const boost::wave::cpplexer::lex_token
<>::position_type
50 //typedef pos_iterator_type::token_type::position_type position_type;
52 position_type
&begin_pos(begin
->get_position());
54 strm_
<< "Parsed " << rule_type_
<< std::endl
;
55 strm_
<< " from: " << begin_pos
.get_file()
56 << "(" << begin_pos
.get_line() << ")"
62 char const* const rule_type_
;
65 #define HANNIBAL_TRACE_ACTION( type) [trace_actor( (type), std::cout)]
67 #define HANNIBAL_TRACE_ACTION( type)
70 ///////////////////////////////////////////////////////////////////////////////
71 #define HANNIBAL_TRACE_TRANSLATION_UNIT_GRAMMAR \
72 bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_CPP_EXPR_GRAMMAR) \
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) \
83 #define HANNIBAL_REGISTER_RULE(r) \
84 BOOST_SPIRIT_DEBUG_NODE(r) \
88 ///////////////////////////////////////////////////////////////////////////////
90 template<typename ForwardIterator
>
91 void operator()(ForwardIterator begin
, ForwardIterator end
)
93 std::cerr
<< "*** COULD NOT PARSE THE FOLLOWING ***" << std::endl
;
96 std::cerr
<< begin
->get_value();
102 ///////////////////////////////////////////////////////////////////////////////
103 struct translation_unit_grammar
104 : public boost::spirit::classic::grammar
<translation_unit_grammar
>
106 #if HANNIBAL_DUMP_PARSE_TREE != 0
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.
112 // Please Note: the lifetime of the rule map should at least extend beyond the
113 // call of the definition constructor...
115 typedef std::map
<boost::spirit::classic::parser_id
, std::string
>
118 translation_unit_grammar(rule_map_type
*rule_map_ptr_
= 0)
119 : rule_map_ptr(rule_map_ptr_
)
121 translation_unit_grammar()
124 BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this,
125 "translation_unit_grammar", HANNIBAL_TRACE_TRANSLATION_UNIT_GRAMMAR
);
128 template <typename ScannerT
>
131 // declare non-terminals
132 typedef boost::spirit::classic::rule
<ScannerT
> rule_type
;
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
;
139 rule_type add_exp
, multiply_exp
;
140 rule_type unary_exp
, primary_exp
, constant
;
142 boost::spirit::classic::subrule
<0> const_exp_subrule
;
143 boost::spirit::classic::subrule
<1> shift_exp_clos
;
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
;
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
;
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
;
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
;
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
;
250 rule_type primary_expression
;
253 // grammar definition.
255 definition(translation_unit_grammar
const& self
)
257 using namespace boost::spirit::classic
;
258 using namespace boost::wave
;
259 using boost::wave::util::pattern_p
;
262 // First, a long list of expression rules.
264 HANNIBAL_REGISTER_RULE( primary_expression
);
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
)
275 HANNIBAL_REGISTER_RULE( literal
);
284 HANNIBAL_REGISTER_RULE( integer_literal
);
286 = pattern_p( IntegerLiteralTokenType
, TokenTypeMask
)
289 HANNIBAL_REGISTER_RULE( character_literal
);
291 = pattern_p( CharacterLiteralTokenType
, TokenTypeMask
)
294 HANNIBAL_REGISTER_RULE( floating_literal
);
296 = pattern_p( FloatingLiteralTokenType
, TokenTypeMask
)
299 HANNIBAL_REGISTER_RULE( string_literal
);
301 = pattern_p( StringLiteralTokenType
, TokenTypeMask
)
304 HANNIBAL_REGISTER_RULE( boolean_literal
);
306 = pattern_p( BoolLiteralTokenType
, TokenTypeMask
)
310 // TODO: separate assignment expression into a grammar of it's own
312 HANNIBAL_REGISTER_RULE( assignment_expression
);
313 assignment_expression
314 = conditional_expression
315 | logical_or_expression
>> assignment_operator
>> assignment_expression
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.
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.
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
340 HANNIBAL_REGISTER_RULE( throw_expression
);
342 = ch_p(T_THROW
) >> !assignment_expression
345 HANNIBAL_REGISTER_RULE( ta_throw_expression
);
347 = ch_p(T_THROW
) >> !ta_assignment_expression
350 HANNIBAL_REGISTER_RULE( conditional_expression
);
351 conditional_expression
352 = logical_or_expression
354 ch_p(T_QUESTION_MARK
)
357 >> assignment_expression
361 HANNIBAL_REGISTER_RULE( ta_conditional_expression
);
362 ta_conditional_expression
363 = ta_logical_or_expression
365 ch_p(T_QUESTION_MARK
)
368 >> ta_assignment_expression
372 HANNIBAL_REGISTER_RULE( expression
);
374 = assignment_expression
% ch_p(T_COMMA
);
376 HANNIBAL_REGISTER_RULE( ta_expression
);
378 = ta_assignment_expression
% ch_p(T_COMMA
);
380 HANNIBAL_REGISTER_RULE( assignment_operator
);
388 | pp(T_PERCENTASSIGN
)
390 | pp(T_SHIFTLEFTASSIGN
)
391 | pp(T_SHIFTRIGHTASSIGN
)
396 // we skip quite a few rules here, since we're not interested in operator precedence
398 HANNIBAL_REGISTER_RULE( logical_or_expression
);
399 logical_or_expression
400 = cast_expression
% expression_operator
403 HANNIBAL_REGISTER_RULE( ta_logical_or_expression
);
404 ta_logical_or_expression
405 = cast_expression
% ta_expression_operator
408 HANNIBAL_REGISTER_RULE( expression_operator
);
410 = ta_expression_operator
| pp(T_GREATER
)
413 HANNIBAL_REGISTER_RULE( ta_expression_operator
);
414 ta_expression_operator
436 HANNIBAL_REGISTER_RULE( cast_expression
);
438 = ch_p(T_LEFTPAREN
) >> type_id
>> ch_p(T_RIGHTPAREN
)
443 HANNIBAL_REGISTER_RULE( unary_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
451 >> ch_p(T_LEFTPAREN
) >> type_id
>> ch_p(T_RIGHTPAREN
)
456 HANNIBAL_REGISTER_RULE( unary_operator
);
466 HANNIBAL_REGISTER_RULE( new_expression
);
468 = !ch_p(T_COLON_COLON
) >> ch_p(T_NEW
) >> !new_placement
470 new_type_id
>> !new_initializer
471 | ch_p(T_LEFTPAREN
) >> type_id
>> ch_p(T_RIGHTPAREN
) >> !new_initializer
475 HANNIBAL_REGISTER_RULE( new_placement
);
477 = ch_p(T_LEFTPAREN
) >> expression_list
>> ch_p(T_RIGHTPAREN
)
480 HANNIBAL_REGISTER_RULE( new_type_id
);
482 = type_specifier_seq
>> !new_declarator
485 HANNIBAL_REGISTER_RULE( new_declarator
);
487 = ptr_operator
>> !new_declarator
488 | direct_new_declarator
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
)
497 HANNIBAL_REGISTER_RULE( new_initializer
);
499 = ch_p(T_LEFTPAREN
) >> !expression_list
>> ch_p(T_RIGHTPAREN
)
502 HANNIBAL_REGISTER_RULE( 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
)
510 HANNIBAL_REGISTER_RULE( postfix_expression
);
512 = simple_postfix_expression
>> *postfix_expression_helper
515 HANNIBAL_REGISTER_RULE( simple_postfix_expression
);
516 simple_postfix_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
)
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
)
530 >> ch_p(T_LESS
) >> type_id
>> ch_p(T_GREATER
)
531 >> ch_p(T_LEFTPAREN
) >> expression
>> ch_p(T_RIGHTPAREN
)
533 >> ch_p(T_LEFTPAREN
) >> expression
>> ch_p(T_RIGHTPAREN
)
535 >> ch_p(T_LEFTPAREN
) >> type_id
>> ch_p(T_RIGHTPAREN
)
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
550 HANNIBAL_REGISTER_RULE( pseudo_destructor_name
);
551 pseudo_destructor_name
552 = !ch_p(T_COLON_COLON
) >> !nested_name_specifier
554 type_name
>> ch_p(T_COLON_COLON
) >> ch_p(T_COMPL
) >> type_name
555 | ch_p(T_COMPL
) >> type_name
560 HANNIBAL_REGISTER_RULE(constant_expression
);
562 = conditional_expression
565 HANNIBAL_REGISTER_RULE(ctor_initializer
);
567 = ch_p(T_COLON
) >> mem_initializer_list
570 HANNIBAL_REGISTER_RULE(mem_initializer_list
);
572 = mem_initializer
% ch_p(T_COMMA
)
575 HANNIBAL_REGISTER_RULE(mem_initializer
);
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)
583 HANNIBAL_REGISTER_RULE(mem_initializer_id
);
585 = !ch_p(T_COLON_COLON
) >> !nested_name_specifier
>> class_name
590 // the eps_p is added to allow skipping of trailing whitespace
593 HANNIBAL_REGISTER_RULE(translation_unit
);
595 = !declaration_seq
>> end_p
;
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
))
604 HANNIBAL_REGISTER_RULE(declaration_seq
);
606 = +declaration
HANNIBAL_TRACE_ACTION( "declaration")
609 HANNIBAL_REGISTER_RULE(declaration
);
611 = template_declaration
612 | explicit_instantiation
613 | explicit_specialization
614 | linkage_specification
615 | namespace_definition
617 | function_definition
620 HANNIBAL_REGISTER_RULE(block_declaration
);
624 | namespace_alias_definition
629 HANNIBAL_REGISTER_RULE(simple_declaration
);
631 = !decl_specifier_seq
>> !init_declarator_list
635 HANNIBAL_REGISTER_RULE(asm_definition
);
638 >> ch_p(T_LEFTPAREN
) >> ch_p(T_STRINGLIT
) >> ch_p(T_RIGHTPAREN
)
642 HANNIBAL_REGISTER_RULE(init_declarator_list
);
644 = init_declarator
% ch_p(T_COMMA
)
647 HANNIBAL_REGISTER_RULE(init_declarator
);
649 = declarator
>> !initializer
652 HANNIBAL_REGISTER_RULE(initializer
);
654 = ch_p(T_ASSIGN
) >> initializer_clause
655 | ch_p(T_LEFTPAREN
) >> expression_list
>> ch_p(T_RIGHTPAREN
)
658 HANNIBAL_REGISTER_RULE(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
)
666 HANNIBAL_REGISTER_RULE(initializer_list
);
668 = initializer_clause
% ch_p(T_COMMA
)
671 HANNIBAL_REGISTER_RULE(expression_list
);
673 = assignment_expression
% ch_p(T_COMMA
)
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
683 HANNIBAL_REGISTER_RULE(qualified_namespace_specifier
);
684 qualified_namespace_specifier
685 = !ch_p(T_COLON_COLON
) >> !nested_name_specifier
689 HANNIBAL_REGISTER_RULE(explicit_instantiation
);
690 explicit_instantiation
691 = template_declaration
694 HANNIBAL_REGISTER_RULE(template_declaration
);
696 = !ch_p(T_EXPORT
) >> ch_p(T_TEMPLATE
)
697 >> ch_p(T_LESS
) >> template_parameter_list
>> ch_p(T_GREATER
)
701 HANNIBAL_REGISTER_RULE(template_parameter_list
);
702 template_parameter_list
703 = template_parameter
% ch_p(T_COMMA
)
706 HANNIBAL_REGISTER_RULE(template_parameter
);
709 | parameter_declaration
712 HANNIBAL_REGISTER_RULE(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
)
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
)
724 HANNIBAL_REGISTER_RULE(template_name
);
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
734 | ch_p(T_USING
) >> ch_p(T_COLON_COLON
) >> unqualified_id
738 HANNIBAL_REGISTER_RULE(using_directive
);
740 = ch_p(T_USING
) >> ch_p(T_NAMESPACE
) >> !ch_p(T_COLON_COLON
)
741 >> !nested_name_specifier
>> namespace_name
745 HANNIBAL_REGISTER_RULE(explicit_specialization
);
746 explicit_specialization
747 = ch_p(T_TEMPLATE
) >> ch_p(T_LESS
) >> ch_p(T_GREATER
)
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
)
759 HANNIBAL_REGISTER_RULE(namespace_definition
);
761 = named_namespace_definition
762 | unnamed_namespace_definition
// TODO: optimize?
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
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
)
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
)
783 HANNIBAL_REGISTER_RULE(original_namespace_name
);
784 original_namespace_name
788 HANNIBAL_REGISTER_RULE(unnamed_namespace_definition
);
789 unnamed_namespace_definition
791 >> ch_p(T_LEFTBRACE
) >> namespace_body
>> ch_p(T_RIGHTBRACE
)
794 HANNIBAL_REGISTER_RULE(namespace_body
);
799 HANNIBAL_REGISTER_RULE(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
807 HANNIBAL_REGISTER_RULE(function_definition_helper
);
808 function_definition_helper
809 = decl_specifier_seq
>> declarator
810 | +no_type_decl_specifier
>> declarator
814 HANNIBAL_REGISTER_RULE(function_try_block
);
817 >> !ctor_initializer
>> function_body
>> handler_seq
820 HANNIBAL_REGISTER_RULE(handler_seq
);
825 HANNIBAL_REGISTER_RULE(handler
);
828 >> comment_nest_p(ch_p(T_LEFTPAREN
), ch_p(T_RIGHTPAREN
))
829 >> compound_statement
832 HANNIBAL_REGISTER_RULE(declarator
);
835 | odd_language_extension
840 HANNIBAL_REGISTER_RULE(direct_declarator
);
843 | ch_p(T_LEFTPAREN
) >> declarator
>> ch_p(T_RIGHTPAREN
)
845 >> *parameters_or_array_spec
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
)
855 HANNIBAL_REGISTER_RULE(exception_specification
);
856 exception_specification
// TODO
858 >> comment_nest_p(ch_p(T_LEFTPAREN
), ch_p(T_RIGHTPAREN
))
861 HANNIBAL_REGISTER_RULE(abstract_declarator
);
864 | odd_language_extension
866 >> !direct_abstract_declarator
867 | direct_abstract_declarator
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
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
)
883 HANNIBAL_REGISTER_RULE(parameter_declaration_clause
);
884 parameter_declaration_clause
885 = parameter_declaration_list
>> ch_p(T_COMMA
)
887 | !parameter_declaration_list
>> !ch_p(T_ELLIPSIS
)
890 HANNIBAL_REGISTER_RULE(parameter_declaration_list
);
891 parameter_declaration_list
892 = parameter_declaration
% ch_p(T_COMMA
)
896 HANNIBAL_REGISTER_RULE(parameter_declaration
);
897 parameter_declaration
899 >> !(declarator
| abstract_declarator
)
900 >> !(ch_p(T_ASSIGN
) >> assignment_expression
)
903 HANNIBAL_REGISTER_RULE(declarator_id
);
905 = !ch_p(T_COLON_COLON
)
907 | !nested_name_specifier
>> type_name
911 HANNIBAL_REGISTER_RULE(id_expression
);
917 HANNIBAL_REGISTER_RULE(qualified_id
);
919 = nested_name_specifier
>> !ch_p(T_TEMPLATE
) >> unqualified_id
922 HANNIBAL_REGISTER_RULE(unqualified_id
);
924 = operator_function_id
925 | conversion_function_id
926 | ch_p(T_COMPL
) >> class_name
931 HANNIBAL_REGISTER_RULE(operator_function_id
);
933 = ch_p(T_OPERATOR
) >> operator_sym
// this is called 'operator' in the std grammar
936 HANNIBAL_REGISTER_RULE(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
)
945 HANNIBAL_REGISTER_RULE(conversion_function_id
);
946 conversion_function_id
947 = ch_p(T_OPERATOR
) >> conversion_type_id
950 HANNIBAL_REGISTER_RULE( conversion_type_id
);
952 = type_specifier_seq
>> !conversion_declarator
955 HANNIBAL_REGISTER_RULE(type_id
);
957 = type_specifier_seq
>> !abstract_declarator
961 HANNIBAL_REGISTER_RULE(conversion_declarator
);
962 conversion_declarator
963 = ptr_operator
>> !conversion_declarator
966 HANNIBAL_REGISTER_RULE(function_body
);
971 HANNIBAL_REGISTER_RULE(compound_statement
);
973 = comment_nest_p(ch_p(T_LEFTBRACE
), ch_p(T_RIGHTBRACE
))
977 HANNIBAL_REGISTER_RULE(ptr_operator
);
979 = ch_p(T_STAR
) >> !cv_qualifier_seq
981 | !ch_p(T_COLON_COLON
) >> nested_name_specifier
982 >> ch_p(T_STAR
) >> !cv_qualifier_seq
986 HANNIBAL_REGISTER_RULE(decl_specifier
);
988 = no_type_decl_specifier
992 HANNIBAL_REGISTER_RULE(no_type_decl_specifier
);
993 no_type_decl_specifier
994 = storage_class_specifier
999 | odd_language_extension
1002 HANNIBAL_REGISTER_RULE(type_specifier_seq
);
1007 HANNIBAL_REGISTER_RULE(type_specifier
);
1011 | elaborated_type_specifier
1012 | simple_type_specifier
1016 HANNIBAL_REGISTER_RULE(cv_qualifier_seq
);
1018 = cv_qualifier
>> !cv_qualifier_seq
1021 HANNIBAL_REGISTER_RULE(cv_qualifier
);
1027 HANNIBAL_REGISTER_RULE(enum_specifier
);
1029 = enum_keyword
>> !ch_p(T_IDENTIFIER
)
1030 >> ch_p(T_LEFTBRACE
) >> !enumerator_list
>> ch_p(T_RIGHTBRACE
)
1033 HANNIBAL_REGISTER_RULE(enum_keyword
);
1038 HANNIBAL_REGISTER_RULE(enumerator_list
);
1040 = enumerator_definition
% 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.
1046 HANNIBAL_REGISTER_RULE(enumerator_definition
);
1047 enumerator_definition
1048 = enumerator
>> !(ch_p(T_ASSIGN
) >> constant_expression
)
1051 HANNIBAL_REGISTER_RULE(enumerator
);
1053 = ch_p(T_IDENTIFIER
)
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
1062 | !ch_p(T_COLON_COLON
) >> !nested_name_specifier
>> type_name
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
1070 !nested_name_specifier
>> template_id
1071 | nested_name_specifier
>> ch_p(T_IDENTIFIER
)
1072 | !ch_p(T_IDENTIFIER
)
1077 HANNIBAL_REGISTER_RULE(type_name
);
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
1090 !ch_p(T_TEMPLATE
) >> template_id
1091 | ch_p(T_IDENTIFIER
)
1093 | ch_p(T_ENUM
) >> !ch_p(T_COLON_COLON
)
1094 >> !nested_name_specifier
1095 >> ch_p(T_IDENTIFIER
)
1097 >> !ch_p(T_COLON_COLON
)
1098 >> nested_name_specifier
1100 !ch_p(T_TEMPLATE
) >> template_id
1101 | ch_p(T_IDENTIFIER
)
1105 HANNIBAL_REGISTER_RULE(template_argument_list
);
1106 template_argument_list
1107 = template_argument
% ch_p(T_COMMA
)
1110 HANNIBAL_REGISTER_RULE(template_argument
);
1115 | ta_assignment_expression
1120 HANNIBAL_REGISTER_RULE(class_key
);
1125 HANNIBAL_REGISTER_RULE(class_keywords
);
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
1140 HANNIBAL_REGISTER_RULE(class_or_namespace_name
);
1141 class_or_namespace_name
1146 HANNIBAL_REGISTER_RULE(class_name
);
1149 | ch_p(T_IDENTIFIER
)
1152 HANNIBAL_REGISTER_RULE(enum_name
);
1154 = ch_p(T_IDENTIFIER
)
1157 HANNIBAL_REGISTER_RULE(typedef_name
);
1159 = ch_p(T_IDENTIFIER
)
1162 HANNIBAL_REGISTER_RULE(namespace_name
);
1163 namespace_name
// TODO
1164 = ch_p(T_IDENTIFIER
)
1167 HANNIBAL_REGISTER_RULE(template_id
);
1170 >> ch_p(T_LESS
) >> template_argument_list
>> ch_p(T_GREATER
)
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.
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
1189 HANNIBAL_REGISTER_RULE(decl_specifier_seq
);
1191 = *no_type_decl_specifier
>> type_specifier
>> *no_type_decl_specifier
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 ))
1200 HANNIBAL_REGISTER_RULE( storage_class_specifier
);
1201 storage_class_specifier
1209 HANNIBAL_REGISTER_RULE( function_specifier
);
1216 HANNIBAL_REGISTER_RULE(class_specifier
);
1219 >> ch_p(T_LEFTBRACE
) >> !member_specification
>> ch_p(T_RIGHTBRACE
)
1222 HANNIBAL_REGISTER_RULE(member_specification
);
1223 member_specification
1224 = +( access_specifier
>> ch_p(T_COLON
)
1225 | member_declaration
HANNIBAL_TRACE_ACTION("member declaration")
1229 // member_specification
1230 // = access_specifier >> COLON_T >> !member_specification
1231 // | member_declaration >> !member_specification
1234 HANNIBAL_REGISTER_RULE(member_declaration
);
1237 | template_declaration
1238 | !decl_specifier_seq
>> !member_declarator_list
1239 >> ch_p(T_SEMICOLON
)
1240 | function_definition
>>
1243 >> ch_p(T_SEMICOLON
)
1246 HANNIBAL_REGISTER_RULE(member_declarator_list
);
1247 member_declarator_list
1248 = member_declarator
% ch_p(T_COMMA
)
1251 HANNIBAL_REGISTER_RULE(member_declarator
);
1253 = !ch_p(T_IDENTIFIER
) >> ch_p(T_COLON
) >> constant_expression
1254 | declarator
>> !(pure_specifier
| constant_initializer
)
1257 HANNIBAL_REGISTER_RULE(pure_specifier
);
1259 = ch_p(T_ASSIGN
) >> ch_p(T_INTLIT
)
1262 HANNIBAL_REGISTER_RULE(constant_initializer
);
1263 constant_initializer
1264 = ch_p(T_ASSIGN
) >> constant_expression
1267 HANNIBAL_REGISTER_RULE(access_specifier
);
1274 HANNIBAL_REGISTER_RULE(base_clause
);
1276 = ch_p(T_COLON
) >> base_specifier_list
1279 HANNIBAL_REGISTER_RULE(base_specifier_list
);
1281 = base_specifier
% ch_p(T_COMMA
)
1284 HANNIBAL_REGISTER_RULE(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
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
)
1302 HANNIBAL_REGISTER_RULE(simple_type_name
);
1315 | ch_p(T_MSEXT_INT64
)
1316 | ch_p(T_MSEXT_INT8
)
1317 | ch_p(T_MSEXT_INT16
)
1318 | ch_p(T_MSEXT_INT32
)
1322 rule_type
const& start() const { return translation_unit
; }
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
)
1328 using namespace boost::wave
;
1329 return util::pattern_p(id
, MainTokenMask
);
1333 #if HANNIBAL_DUMP_PARSE_TREE != 0
1335 template<typename Rule
>
1336 void declare_rule(Rule
const& rule
, std::string
const& rule_name
) const
1339 (*rule_map_ptr
)[rule
.id()] = rule_name
;
1341 rule_map_type
*rule_map_ptr
;
1345 #undef HANNIBAL_REGISTER_RULE
1346 #undef HANNIBAL_TRACE_TRANSLATION_UNIT_GRAMMAR
1348 #endif // BOOST_HANNIBAL_TRANSLATION_UNIT_GRAMMAR_H_INCLUDED