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