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(HANNIBAL_TRANSLATION_UNIT_GRAMMAR_H_INCLUDED)
13 #define HANNIBAL_TRANSLATION_UNIT_GRAMMAR_H_INCLUDED
17 #include <boost/assert.hpp>
18 #include <boost/spirit/include/classic_core.hpp>
19 #include <boost/spirit/include/classic_confix.hpp>
21 #include <boost/wave/wave_config.hpp>
22 #include <boost/wave/token_ids.hpp>
23 #include <boost/wave/util/pattern_parser.hpp>
26 // If so required, trace every declaration and member-declaration.
27 // This can be a much faster alternative to BOOST_SPIRIT_DEBUG-type of
30 #ifdef HANNIBAL_TRACE_DECLARATIONS
34 const char rule_type
[],
37 : strm_( strm
), rule_type_( rule_type
)
42 template<typename PositionIterator
>
43 void operator()(PositionIterator begin
, PositionIterator end
) const
45 typedef const boost::wave::cpplexer::lex_token
<>::position_type
47 //typedef pos_iterator_type::token_type::position_type position_type;
49 position_type
&begin_pos(begin
->get_position());
51 strm_
<< "Parsed " << rule_type_
<< std::endl
;
52 strm_
<< " from: " << begin_pos
.get_file()
53 << "(" << begin_pos
.get_line() << ")"
59 char const* const rule_type_
;
62 #define HANNIBAL_TRACE_ACTION( type) [trace_actor( (type), std::cout)]
64 #define HANNIBAL_TRACE_ACTION( type)
67 ///////////////////////////////////////////////////////////////////////////////
68 #define HANNIBAL_TRACE_TRANSLATION_UNIT_GRAMMAR \
69 bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_CPP_EXPR_GRAMMAR) \
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) \
80 #define HANNIBAL_REGISTER_RULE(r) \
81 BOOST_SPIRIT_DEBUG_NODE(r) \
85 ///////////////////////////////////////////////////////////////////////////////
87 template<typename ForwardIterator
>
88 void operator()(ForwardIterator begin
, ForwardIterator end
)
90 std::cerr
<< "*** COULD NOT PARSE THE FOLLOWING ***" << std::endl
;
93 std::cerr
<< begin
->get_value();
99 ///////////////////////////////////////////////////////////////////////////////
100 struct translation_unit_grammar
101 : public boost::spirit::classic::grammar
<translation_unit_grammar
>
103 #if HANNIBAL_DUMP_PARSE_TREE != 0
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.
109 // Please Note: the lifetime of the rule map should at least extend beyond the
110 // call of the definition constructor...
112 typedef std::map
<boost::spirit::classic::parser_id
, std::string
>
115 translation_unit_grammar(rule_map_type
*rule_map_ptr_
= 0)
116 : rule_map_ptr(rule_map_ptr_
)
118 translation_unit_grammar()
121 BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this,
122 "translation_unit_grammar", HANNIBAL_TRACE_TRANSLATION_UNIT_GRAMMAR
);
125 template <typename ScannerT
>
128 // declare non-terminals
129 typedef boost::spirit::classic::rule
<ScannerT
> rule_type
;
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
;
136 rule_type add_exp
, multiply_exp
;
137 rule_type unary_exp
, primary_exp
, constant
;
139 boost::spirit::classic::subrule
<0> const_exp_subrule
;
140 boost::spirit::classic::subrule
<1> shift_exp_clos
;
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
;
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
;
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
;
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
;
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
;
247 rule_type primary_expression
;
250 // grammar definition.
252 definition(translation_unit_grammar
const& self
)
254 using namespace boost::spirit::classic
;
255 using namespace boost::wave
;
256 using boost::wave::util::pattern_p
;
259 // First, a long list of expression rules.
261 HANNIBAL_REGISTER_RULE( primary_expression
);
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
)
272 HANNIBAL_REGISTER_RULE( literal
);
281 HANNIBAL_REGISTER_RULE( integer_literal
);
283 = pattern_p( IntegerLiteralTokenType
, TokenTypeMask
)
286 HANNIBAL_REGISTER_RULE( character_literal
);
288 = pattern_p( CharacterLiteralTokenType
, TokenTypeMask
)
291 HANNIBAL_REGISTER_RULE( floating_literal
);
293 = pattern_p( FloatingLiteralTokenType
, TokenTypeMask
)
296 HANNIBAL_REGISTER_RULE( string_literal
);
298 = pattern_p( StringLiteralTokenType
, TokenTypeMask
)
301 HANNIBAL_REGISTER_RULE( boolean_literal
);
303 = pattern_p( BoolLiteralTokenType
, TokenTypeMask
)
307 // TODO: separate assignment expression into a grammar of it's own
309 HANNIBAL_REGISTER_RULE( assignment_expression
);
310 assignment_expression
311 = conditional_expression
312 | logical_or_expression
>> assignment_operator
>> assignment_expression
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.
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.
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
337 HANNIBAL_REGISTER_RULE( throw_expression
);
339 = ch_p(T_THROW
) >> !assignment_expression
342 HANNIBAL_REGISTER_RULE( ta_throw_expression
);
344 = ch_p(T_THROW
) >> !ta_assignment_expression
347 HANNIBAL_REGISTER_RULE( conditional_expression
);
348 conditional_expression
349 = logical_or_expression
351 ch_p(T_QUESTION_MARK
)
354 >> assignment_expression
358 HANNIBAL_REGISTER_RULE( ta_conditional_expression
);
359 ta_conditional_expression
360 = ta_logical_or_expression
362 ch_p(T_QUESTION_MARK
)
365 >> ta_assignment_expression
369 HANNIBAL_REGISTER_RULE( expression
);
371 = assignment_expression
% ch_p(T_COMMA
);
373 HANNIBAL_REGISTER_RULE( ta_expression
);
375 = ta_assignment_expression
% ch_p(T_COMMA
);
377 HANNIBAL_REGISTER_RULE( assignment_operator
);
385 | pp(T_PERCENTASSIGN
)
387 | pp(T_SHIFTLEFTASSIGN
)
388 | pp(T_SHIFTRIGHTASSIGN
)
393 // we skip quite a few rules here, since we're not interested in operator precedence
395 HANNIBAL_REGISTER_RULE( logical_or_expression
);
396 logical_or_expression
397 = cast_expression
% expression_operator
400 HANNIBAL_REGISTER_RULE( ta_logical_or_expression
);
401 ta_logical_or_expression
402 = cast_expression
% ta_expression_operator
405 HANNIBAL_REGISTER_RULE( expression_operator
);
407 = ta_expression_operator
| pp(T_GREATER
)
410 HANNIBAL_REGISTER_RULE( ta_expression_operator
);
411 ta_expression_operator
433 HANNIBAL_REGISTER_RULE( cast_expression
);
435 = ch_p(T_LEFTPAREN
) >> type_id
>> ch_p(T_RIGHTPAREN
)
440 HANNIBAL_REGISTER_RULE( unary_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
448 >> ch_p(T_LEFTPAREN
) >> type_id
>> ch_p(T_RIGHTPAREN
)
453 HANNIBAL_REGISTER_RULE( unary_operator
);
463 HANNIBAL_REGISTER_RULE( new_expression
);
465 = !ch_p(T_COLON_COLON
) >> ch_p(T_NEW
) >> !new_placement
467 new_type_id
>> !new_initializer
468 | ch_p(T_LEFTPAREN
) >> type_id
>> ch_p(T_RIGHTPAREN
) >> !new_initializer
472 HANNIBAL_REGISTER_RULE( new_placement
);
474 = ch_p(T_LEFTPAREN
) >> expression_list
>> ch_p(T_RIGHTPAREN
)
477 HANNIBAL_REGISTER_RULE( new_type_id
);
479 = type_specifier_seq
>> !new_declarator
482 HANNIBAL_REGISTER_RULE( new_declarator
);
484 = ptr_operator
>> !new_declarator
485 | direct_new_declarator
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
)
494 HANNIBAL_REGISTER_RULE( new_initializer
);
496 = ch_p(T_LEFTPAREN
) >> !expression_list
>> ch_p(T_RIGHTPAREN
)
499 HANNIBAL_REGISTER_RULE( 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
)
507 HANNIBAL_REGISTER_RULE( postfix_expression
);
509 = simple_postfix_expression
>> *postfix_expression_helper
512 HANNIBAL_REGISTER_RULE( simple_postfix_expression
);
513 simple_postfix_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
)
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
)
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_LEFTPAREN
) >> expression
>> ch_p(T_RIGHTPAREN
)
532 >> ch_p(T_LEFTPAREN
) >> type_id
>> ch_p(T_RIGHTPAREN
)
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
547 HANNIBAL_REGISTER_RULE( pseudo_destructor_name
);
548 pseudo_destructor_name
549 = !ch_p(T_COLON_COLON
) >> !nested_name_specifier
551 type_name
>> ch_p(T_COLON_COLON
) >> ch_p(T_COMPL
) >> type_name
552 | ch_p(T_COMPL
) >> type_name
557 HANNIBAL_REGISTER_RULE(constant_expression
);
559 = conditional_expression
562 HANNIBAL_REGISTER_RULE(ctor_initializer
);
564 = ch_p(T_COLON
) >> mem_initializer_list
567 HANNIBAL_REGISTER_RULE(mem_initializer_list
);
569 = mem_initializer
% ch_p(T_COMMA
)
572 HANNIBAL_REGISTER_RULE(mem_initializer
);
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)
580 HANNIBAL_REGISTER_RULE(mem_initializer_id
);
582 = !ch_p(T_COLON_COLON
) >> !nested_name_specifier
>> class_name
587 // the eps_p is added to allow skipping of trailing whitespace
590 HANNIBAL_REGISTER_RULE(translation_unit
);
592 = !declaration_seq
>> end_p
;
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
))
601 HANNIBAL_REGISTER_RULE(declaration_seq
);
603 = +declaration
HANNIBAL_TRACE_ACTION( "declaration")
606 HANNIBAL_REGISTER_RULE(declaration
);
608 = template_declaration
609 | explicit_instantiation
610 | explicit_specialization
611 | linkage_specification
612 | namespace_definition
614 | function_definition
617 HANNIBAL_REGISTER_RULE(block_declaration
);
621 | namespace_alias_definition
626 HANNIBAL_REGISTER_RULE(simple_declaration
);
628 = !decl_specifier_seq
>> !init_declarator_list
632 HANNIBAL_REGISTER_RULE(asm_definition
);
635 >> ch_p(T_LEFTPAREN
) >> ch_p(T_STRINGLIT
) >> ch_p(T_RIGHTPAREN
)
639 HANNIBAL_REGISTER_RULE(init_declarator_list
);
641 = init_declarator
% ch_p(T_COMMA
)
644 HANNIBAL_REGISTER_RULE(init_declarator
);
646 = declarator
>> !initializer
649 HANNIBAL_REGISTER_RULE(initializer
);
651 = ch_p(T_ASSIGN
) >> initializer_clause
652 | ch_p(T_LEFTPAREN
) >> expression_list
>> ch_p(T_RIGHTPAREN
)
655 HANNIBAL_REGISTER_RULE(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
)
663 HANNIBAL_REGISTER_RULE(initializer_list
);
665 = initializer_clause
% ch_p(T_COMMA
)
668 HANNIBAL_REGISTER_RULE(expression_list
);
670 = assignment_expression
% ch_p(T_COMMA
)
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
680 HANNIBAL_REGISTER_RULE(qualified_namespace_specifier
);
681 qualified_namespace_specifier
682 = !ch_p(T_COLON_COLON
) >> !nested_name_specifier
686 HANNIBAL_REGISTER_RULE(explicit_instantiation
);
687 explicit_instantiation
688 = template_declaration
691 HANNIBAL_REGISTER_RULE(template_declaration
);
693 = !ch_p(T_EXPORT
) >> ch_p(T_TEMPLATE
)
694 >> ch_p(T_LESS
) >> template_parameter_list
>> ch_p(T_GREATER
)
698 HANNIBAL_REGISTER_RULE(template_parameter_list
);
699 template_parameter_list
700 = template_parameter
% ch_p(T_COMMA
)
703 HANNIBAL_REGISTER_RULE(template_parameter
);
706 | parameter_declaration
709 HANNIBAL_REGISTER_RULE(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
)
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
)
721 HANNIBAL_REGISTER_RULE(template_name
);
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
731 | ch_p(T_USING
) >> ch_p(T_COLON_COLON
) >> unqualified_id
735 HANNIBAL_REGISTER_RULE(using_directive
);
737 = ch_p(T_USING
) >> ch_p(T_NAMESPACE
) >> !ch_p(T_COLON_COLON
)
738 >> !nested_name_specifier
>> namespace_name
742 HANNIBAL_REGISTER_RULE(explicit_specialization
);
743 explicit_specialization
744 = ch_p(T_TEMPLATE
) >> ch_p(T_LESS
) >> ch_p(T_GREATER
)
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
)
756 HANNIBAL_REGISTER_RULE(namespace_definition
);
758 = named_namespace_definition
759 | unnamed_namespace_definition
// TODO: optimize?
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
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
)
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
)
780 HANNIBAL_REGISTER_RULE(original_namespace_name
);
781 original_namespace_name
785 HANNIBAL_REGISTER_RULE(unnamed_namespace_definition
);
786 unnamed_namespace_definition
788 >> ch_p(T_LEFTBRACE
) >> namespace_body
>> ch_p(T_RIGHTBRACE
)
791 HANNIBAL_REGISTER_RULE(namespace_body
);
796 HANNIBAL_REGISTER_RULE(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
804 HANNIBAL_REGISTER_RULE(function_definition_helper
);
805 function_definition_helper
806 = decl_specifier_seq
>> declarator
807 | +no_type_decl_specifier
>> declarator
811 HANNIBAL_REGISTER_RULE(function_try_block
);
814 >> !ctor_initializer
>> function_body
>> handler_seq
817 HANNIBAL_REGISTER_RULE(handler_seq
);
822 HANNIBAL_REGISTER_RULE(handler
);
825 >> comment_nest_p(ch_p(T_LEFTPAREN
), ch_p(T_RIGHTPAREN
))
826 >> compound_statement
829 HANNIBAL_REGISTER_RULE(declarator
);
832 | odd_language_extension
837 HANNIBAL_REGISTER_RULE(direct_declarator
);
840 | ch_p(T_LEFTPAREN
) >> declarator
>> ch_p(T_RIGHTPAREN
)
842 >> *parameters_or_array_spec
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
)
852 HANNIBAL_REGISTER_RULE(exception_specification
);
853 exception_specification
// TODO
855 >> comment_nest_p(ch_p(T_LEFTPAREN
), ch_p(T_RIGHTPAREN
))
858 HANNIBAL_REGISTER_RULE(abstract_declarator
);
861 | odd_language_extension
863 >> !direct_abstract_declarator
864 | direct_abstract_declarator
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
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
)
880 HANNIBAL_REGISTER_RULE(parameter_declaration_clause
);
881 parameter_declaration_clause
882 = parameter_declaration_list
>> ch_p(T_COMMA
)
884 | !parameter_declaration_list
>> !ch_p(T_ELLIPSIS
)
887 HANNIBAL_REGISTER_RULE(parameter_declaration_list
);
888 parameter_declaration_list
889 = parameter_declaration
% ch_p(T_COMMA
)
893 HANNIBAL_REGISTER_RULE(parameter_declaration
);
894 parameter_declaration
896 >> !(declarator
| abstract_declarator
)
897 >> !(ch_p(T_ASSIGN
) >> assignment_expression
)
900 HANNIBAL_REGISTER_RULE(declarator_id
);
902 = !ch_p(T_COLON_COLON
)
904 | !nested_name_specifier
>> type_name
908 HANNIBAL_REGISTER_RULE(id_expression
);
914 HANNIBAL_REGISTER_RULE(qualified_id
);
916 = nested_name_specifier
>> !ch_p(T_TEMPLATE
) >> unqualified_id
919 HANNIBAL_REGISTER_RULE(unqualified_id
);
921 = operator_function_id
922 | conversion_function_id
923 | ch_p(T_COMPL
) >> class_name
928 HANNIBAL_REGISTER_RULE(operator_function_id
);
930 = ch_p(T_OPERATOR
) >> operator_sym
// this is called 'operator' in the std grammar
933 HANNIBAL_REGISTER_RULE(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
)
942 HANNIBAL_REGISTER_RULE(conversion_function_id
);
943 conversion_function_id
944 = ch_p(T_OPERATOR
) >> conversion_type_id
947 HANNIBAL_REGISTER_RULE( conversion_type_id
);
949 = type_specifier_seq
>> !conversion_declarator
952 HANNIBAL_REGISTER_RULE(type_id
);
954 = type_specifier_seq
>> !abstract_declarator
958 HANNIBAL_REGISTER_RULE(conversion_declarator
);
959 conversion_declarator
960 = ptr_operator
>> !conversion_declarator
963 HANNIBAL_REGISTER_RULE(function_body
);
968 HANNIBAL_REGISTER_RULE(compound_statement
);
970 = comment_nest_p(ch_p(T_LEFTBRACE
), ch_p(T_RIGHTBRACE
))
974 HANNIBAL_REGISTER_RULE(ptr_operator
);
976 = ch_p(T_STAR
) >> !cv_qualifier_seq
978 | !ch_p(T_COLON_COLON
) >> nested_name_specifier
979 >> ch_p(T_STAR
) >> !cv_qualifier_seq
983 HANNIBAL_REGISTER_RULE(decl_specifier
);
985 = no_type_decl_specifier
989 HANNIBAL_REGISTER_RULE(no_type_decl_specifier
);
990 no_type_decl_specifier
991 = storage_class_specifier
996 | odd_language_extension
999 HANNIBAL_REGISTER_RULE(type_specifier_seq
);
1004 HANNIBAL_REGISTER_RULE(type_specifier
);
1008 | elaborated_type_specifier
1009 | simple_type_specifier
1013 HANNIBAL_REGISTER_RULE(cv_qualifier_seq
);
1015 = cv_qualifier
>> !cv_qualifier_seq
1018 HANNIBAL_REGISTER_RULE(cv_qualifier
);
1024 HANNIBAL_REGISTER_RULE(enum_specifier
);
1026 = enum_keyword
>> !ch_p(T_IDENTIFIER
)
1027 >> ch_p(T_LEFTBRACE
) >> !enumerator_list
>> ch_p(T_RIGHTBRACE
)
1030 HANNIBAL_REGISTER_RULE(enum_keyword
);
1035 HANNIBAL_REGISTER_RULE(enumerator_list
);
1037 = enumerator_definition
% 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.
1043 HANNIBAL_REGISTER_RULE(enumerator_definition
);
1044 enumerator_definition
1045 = enumerator
>> !(ch_p(T_ASSIGN
) >> constant_expression
)
1048 HANNIBAL_REGISTER_RULE(enumerator
);
1050 = ch_p(T_IDENTIFIER
)
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
1059 | !ch_p(T_COLON_COLON
) >> !nested_name_specifier
>> type_name
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
1067 !nested_name_specifier
>> template_id
1068 | nested_name_specifier
>> ch_p(T_IDENTIFIER
)
1069 | !ch_p(T_IDENTIFIER
)
1074 HANNIBAL_REGISTER_RULE(type_name
);
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
1087 !ch_p(T_TEMPLATE
) >> template_id
1088 | ch_p(T_IDENTIFIER
)
1090 | ch_p(T_ENUM
) >> !ch_p(T_COLON_COLON
)
1091 >> !nested_name_specifier
1092 >> ch_p(T_IDENTIFIER
)
1094 >> !ch_p(T_COLON_COLON
)
1095 >> nested_name_specifier
1097 !ch_p(T_TEMPLATE
) >> template_id
1098 | ch_p(T_IDENTIFIER
)
1102 HANNIBAL_REGISTER_RULE(template_argument_list
);
1103 template_argument_list
1104 = template_argument
% ch_p(T_COMMA
)
1107 HANNIBAL_REGISTER_RULE(template_argument
);
1112 | ta_assignment_expression
1117 HANNIBAL_REGISTER_RULE(class_key
);
1122 HANNIBAL_REGISTER_RULE(class_keywords
);
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
1137 HANNIBAL_REGISTER_RULE(class_or_namespace_name
);
1138 class_or_namespace_name
1143 HANNIBAL_REGISTER_RULE(class_name
);
1146 | ch_p(T_IDENTIFIER
)
1149 HANNIBAL_REGISTER_RULE(enum_name
);
1151 = ch_p(T_IDENTIFIER
)
1154 HANNIBAL_REGISTER_RULE(typedef_name
);
1156 = ch_p(T_IDENTIFIER
)
1159 HANNIBAL_REGISTER_RULE(namespace_name
);
1160 namespace_name
// TODO
1161 = ch_p(T_IDENTIFIER
)
1164 HANNIBAL_REGISTER_RULE(template_id
);
1167 >> ch_p(T_LESS
) >> template_argument_list
>> ch_p(T_GREATER
)
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.
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
1186 HANNIBAL_REGISTER_RULE(decl_specifier_seq
);
1188 = *no_type_decl_specifier
>> type_specifier
>> *no_type_decl_specifier
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 ))
1197 HANNIBAL_REGISTER_RULE( storage_class_specifier
);
1198 storage_class_specifier
1206 HANNIBAL_REGISTER_RULE( function_specifier
);
1213 HANNIBAL_REGISTER_RULE(class_specifier
);
1216 >> ch_p(T_LEFTBRACE
) >> !member_specification
>> ch_p(T_RIGHTBRACE
)
1219 HANNIBAL_REGISTER_RULE(member_specification
);
1220 member_specification
1221 = +( access_specifier
>> ch_p(T_COLON
)
1222 | member_declaration
HANNIBAL_TRACE_ACTION("member declaration")
1226 // member_specification
1227 // = access_specifier >> COLON_T >> !member_specification
1228 // | member_declaration >> !member_specification
1231 HANNIBAL_REGISTER_RULE(member_declaration
);
1234 | template_declaration
1235 | !decl_specifier_seq
>> !member_declarator_list
1236 >> ch_p(T_SEMICOLON
)
1237 | function_definition
>>
1240 >> ch_p(T_SEMICOLON
)
1243 HANNIBAL_REGISTER_RULE(member_declarator_list
);
1244 member_declarator_list
1245 = member_declarator
% ch_p(T_COMMA
)
1248 HANNIBAL_REGISTER_RULE(member_declarator
);
1250 = !ch_p(T_IDENTIFIER
) >> ch_p(T_COLON
) >> constant_expression
1251 | declarator
>> !(pure_specifier
| constant_initializer
)
1254 HANNIBAL_REGISTER_RULE(pure_specifier
);
1256 = ch_p(T_ASSIGN
) >> ch_p(T_INTLIT
)
1259 HANNIBAL_REGISTER_RULE(constant_initializer
);
1260 constant_initializer
1261 = ch_p(T_ASSIGN
) >> constant_expression
1264 HANNIBAL_REGISTER_RULE(access_specifier
);
1271 HANNIBAL_REGISTER_RULE(base_clause
);
1273 = ch_p(T_COLON
) >> base_specifier_list
1276 HANNIBAL_REGISTER_RULE(base_specifier_list
);
1278 = base_specifier
% ch_p(T_COMMA
)
1281 HANNIBAL_REGISTER_RULE(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
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
)
1299 HANNIBAL_REGISTER_RULE(simple_type_name
);
1312 | ch_p(T_MSEXT_INT64
)
1313 | ch_p(T_MSEXT_INT8
)
1314 | ch_p(T_MSEXT_INT16
)
1315 | ch_p(T_MSEXT_INT32
)
1319 rule_type
const& start() const { return translation_unit
; }
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
)
1325 using namespace boost::wave
;
1326 return util::pattern_p(id
, MainTokenMask
);
1330 #if HANNIBAL_DUMP_PARSE_TREE != 0
1332 template<typename Rule
>
1333 void declare_rule(Rule
const& rule
, std::string
const& rule_name
) const
1336 (*rule_map_ptr
)[rule
.id()] = rule_name
;
1338 rule_map_type
*rule_map_ptr
;
1342 #undef HANNIBAL_REGISTER_RULE
1343 #undef HANNIBAL_TRACE_TRANSLATION_UNIT_GRAMMAR
1345 #endif // HANNIBAL_TRANSLATION_UNIT_GRAMMAR_H_INCLUDED