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