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 { trace_actortrace_actor33 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> operatortrace_actor43 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> operatordump_actor88 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) rule_map_ptrtranslation_unit_grammar116 : 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 definitiontranslation_unit_grammar::definition252 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 starttranslation_unit_grammar::definition1319 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> pptranslation_unit_grammar::definition1323 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> declare_ruletranslation_unit_grammar1333 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 1346