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(BOOST_HANNIBAL_TRANSLATION_UNIT_GRAMMAR_H_INCLUDED) 13 #define BOOST_HANNIBAL_TRANSLATION_UNIT_GRAMMAR_H_INCLUDED 14 15 #include <map> 16 #if defined(HANNIBAL_TRACE_DECLARATIONS) 17 #include <iostream> 18 #endif 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 { trace_actortrace_actor36 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> operatortrace_actor46 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> operatordump_actor91 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) rule_map_ptrtranslation_unit_grammar119 : 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 definitiontranslation_unit_grammar::definition255 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 starttranslation_unit_grammar::definition1322 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> pptranslation_unit_grammar::definition1326 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> declare_ruletranslation_unit_grammar1336 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 1348 #endif // BOOST_HANNIBAL_TRANSLATION_UNIT_GRAMMAR_H_INCLUDED 1349