Serenity Operating System
at master 1743 lines 53 kB view raw
1/* 2 * Copyright (c) 2021, Itamar S. <itamar8910@gmail.com> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include "Parser.h" 8#include "AST.h" 9#include <AK/Debug.h> 10#include <AK/ScopeGuard.h> 11#include <AK/ScopeLogger.h> 12#include <LibCpp/Lexer.h> 13 14#define LOG_SCOPE() ScopeLogger<CPP_DEBUG> logger(DeprecatedString::formatted("'{}' - {} ({})", peek().text(), peek().type_as_deprecated_string(), m_state.token_index)) 15 16namespace Cpp { 17 18Parser::Parser(Vector<Token> tokens, DeprecatedString const& filename) 19 : m_filename(filename) 20 , m_tokens(move(tokens)) 21{ 22 if constexpr (CPP_DEBUG) { 23 dbgln("Tokens:"); 24 for (size_t i = 0; i < m_tokens.size(); ++i) { 25 dbgln("{}- {}", i, m_tokens[i].to_deprecated_string()); 26 } 27 } 28} 29 30NonnullRefPtr<TranslationUnit> Parser::parse() 31{ 32 LOG_SCOPE(); 33 if (m_tokens.is_empty()) 34 return create_root_ast_node({}, {}); 35 auto unit = create_root_ast_node(m_tokens.first().start(), m_tokens.last().end()); 36 unit->set_declarations(parse_declarations_in_translation_unit(*unit)); 37 return unit; 38} 39 40Vector<NonnullRefPtr<Declaration const>> Parser::parse_declarations_in_translation_unit(ASTNode const& parent) 41{ 42 Vector<NonnullRefPtr<Declaration const>> declarations; 43 while (!eof()) { 44 auto declaration = parse_single_declaration_in_translation_unit(parent); 45 if (declaration) { 46 declarations.append(declaration.release_nonnull()); 47 } else { 48 error("unexpected token"sv); 49 consume(); 50 } 51 } 52 return declarations; 53} 54 55RefPtr<Declaration const> Parser::parse_single_declaration_in_translation_unit(ASTNode const& parent) 56{ 57 while (!eof()) { 58 if (match_comment()) { 59 consume(Token::Type::Comment); 60 continue; 61 } 62 63 if (match_preprocessor()) { 64 consume_preprocessor(); 65 continue; 66 } 67 68 auto declaration = match_declaration_in_translation_unit(); 69 if (declaration.has_value()) { 70 return parse_declaration(parent, declaration.value()); 71 } 72 return {}; 73 } 74 return {}; 75} 76 77NonnullRefPtr<Declaration const> Parser::parse_declaration(ASTNode const& parent, DeclarationType declaration_type) 78{ 79 switch (declaration_type) { 80 case DeclarationType::Function: 81 return parse_function_declaration(parent); 82 case DeclarationType::Variable: 83 return parse_variable_declaration(parent); 84 case DeclarationType::Enum: 85 return parse_enum_declaration(parent); 86 case DeclarationType::Class: 87 return parse_class_declaration(parent); 88 case DeclarationType::Namespace: 89 return parse_namespace_declaration(parent); 90 case DeclarationType::Constructor: 91 return parse_constructor(parent); 92 case DeclarationType::Destructor: 93 return parse_destructor(parent); 94 case DeclarationType::UsingNamespace: 95 return parse_using_namespace_declaration(parent); 96 default: 97 error("unexpected declaration type"sv); 98 return create_ast_node<InvalidDeclaration>(parent, position(), position()); 99 } 100} 101 102NonnullRefPtr<FunctionDeclaration const> Parser::parse_function_declaration(ASTNode const& parent) 103{ 104 auto func = create_ast_node<FunctionDeclaration>(parent, position(), {}); 105 106 func->set_qualifiers(parse_function_qualifiers()); 107 func->set_return_type(parse_type(*func)); 108 109 func->set_name(parse_name(*func)); 110 111 consume(Token::Type::LeftParen); 112 auto parameters = parse_parameter_list(*func); 113 if (parameters.has_value()) 114 func->set_parameters(parameters.value()); 115 116 consume(Token::Type::RightParen); 117 118 while (match_keyword("const") || match_keyword("override")) { 119 consume(); 120 // FIXME: Note that this function is supposed to be a class member, and `this` has to be const, somehow. 121 } 122 123 RefPtr<FunctionDefinition const> body; 124 Position func_end {}; 125 if (peek(Token::Type::LeftCurly).has_value()) { 126 body = parse_function_definition(*func); 127 func_end = body->end(); 128 } else { 129 func_end = position(); 130 if (match_attribute_specification()) 131 consume_attribute_specification(); // we don't use the value of __attribute__ 132 consume(Token::Type::Semicolon); 133 } 134 135 func->set_definition(move(body)); 136 func->set_end(func_end); 137 return func; 138} 139 140NonnullRefPtr<FunctionDefinition const> Parser::parse_function_definition(ASTNode const& parent) 141{ 142 LOG_SCOPE(); 143 auto func = create_ast_node<FunctionDefinition>(parent, position(), {}); 144 consume(Token::Type::LeftCurly); 145 while (!eof() && peek().type() != Token::Type::RightCurly) { 146 func->add_statement(parse_statement(func)); 147 } 148 func->set_end(position()); 149 if (!eof()) 150 consume(Token::Type::RightCurly); 151 return func; 152} 153 154NonnullRefPtr<Statement const> Parser::parse_statement(ASTNode const& parent) 155{ 156 LOG_SCOPE(); 157 ArmedScopeGuard consume_semicolon([this]() { 158 consume(Token::Type::Semicolon); 159 }); 160 161 if (match_block_statement()) { 162 consume_semicolon.disarm(); 163 return parse_block_statement(parent); 164 } 165 if (match_comment()) { 166 consume_semicolon.disarm(); 167 return parse_comment(parent); 168 } 169 if (match_variable_declaration()) { 170 return parse_variable_declaration(parent, false); 171 } 172 if (match_expression()) { 173 return parse_expression(parent); 174 } 175 if (match_keyword("return")) { 176 return parse_return_statement(parent); 177 } 178 if (match_keyword("for")) { 179 consume_semicolon.disarm(); 180 return parse_for_statement(parent); 181 } 182 if (match_keyword("if")) { 183 consume_semicolon.disarm(); 184 return parse_if_statement(parent); 185 } else { 186 error("unexpected statement type"sv); 187 consume_semicolon.disarm(); 188 consume(); 189 return create_ast_node<InvalidStatement>(parent, position(), position()); 190 } 191} 192 193NonnullRefPtr<Comment const> Parser::parse_comment(ASTNode const& parent) 194{ 195 auto comment = create_ast_node<Comment>(parent, position(), {}); 196 consume(Token::Type::Comment); 197 comment->set_end(position()); 198 return comment; 199} 200 201bool Parser::match_block_statement() 202{ 203 return peek().type() == Token::Type::LeftCurly; 204} 205 206NonnullRefPtr<BlockStatement const> Parser::parse_block_statement(ASTNode const& parent) 207{ 208 LOG_SCOPE(); 209 auto block_statement = create_ast_node<BlockStatement>(parent, position(), {}); 210 consume(Token::Type::LeftCurly); 211 while (!eof() && peek().type() != Token::Type::RightCurly) { 212 block_statement->add_statement(parse_statement(*block_statement)); 213 } 214 consume(Token::Type::RightCurly); 215 block_statement->set_end(position()); 216 return block_statement; 217} 218 219bool Parser::match_type() 220{ 221 return match_named_type(); 222} 223 224bool Parser::match_named_type() 225{ 226 save_state(); 227 ScopeGuard state_guard = [this] { load_state(); }; 228 229 parse_type_qualifiers(); 230 if (match_keyword("auto")) { 231 return true; 232 } 233 234 if (match_keyword("struct")) { 235 consume(Token::Type::Keyword); // Consume struct prefix 236 } 237 238 if (!match_name()) 239 return false; 240 241 return true; 242} 243 244bool Parser::match_template_arguments() 245{ 246 save_state(); 247 ScopeGuard state_guard = [this] { load_state(); }; 248 249 if (!peek(Token::Type::Less).has_value()) 250 return false; 251 consume(); 252 253 while (!eof() && peek().type() != Token::Type::Greater) { 254 if (!match_named_type()) 255 return false; 256 (void)parse_type(get_dummy_node()); 257 } 258 259 return peek().type() == Token::Type::Greater; 260} 261 262Vector<NonnullRefPtr<Type const>> Parser::parse_template_arguments(ASTNode const& parent) 263{ 264 LOG_SCOPE(); 265 266 consume(Token::Type::Less); 267 268 Vector<NonnullRefPtr<Type const>> template_arguments; 269 while (!eof() && peek().type() != Token::Type::Greater) { 270 template_arguments.append(parse_type(parent)); 271 } 272 273 consume(Token::Type::Greater); 274 275 return template_arguments; 276} 277 278bool Parser::match_variable_declaration() 279{ 280 LOG_SCOPE(); 281 save_state(); 282 ScopeGuard state_guard = [this] { load_state(); }; 283 284 if (!match_type()) { 285 return false; 286 } 287 288 VERIFY(m_root_node); 289 (void)parse_type(get_dummy_node()); 290 291 // Identifier 292 if (!match_name()) 293 return false; 294 295 (void)parse_name(get_dummy_node()); 296 297 if (match(Token::Type::Equals)) { 298 consume(Token::Type::Equals); 299 if (!match_expression()) { 300 error("initial value of variable is not an expression"sv); 301 return false; 302 } 303 return true; 304 } 305 306 if (match_braced_init_list()) 307 (void)parse_braced_init_list(get_dummy_node()); 308 309 return match(Token::Type::Semicolon); 310} 311 312NonnullRefPtr<VariableDeclaration const> Parser::parse_variable_declaration(ASTNode const& parent, bool expect_semicolon) 313{ 314 LOG_SCOPE(); 315 auto var = create_ast_node<VariableDeclaration>(parent, position(), {}); 316 if (!match_variable_declaration()) { 317 error("unexpected token for variable type"sv); 318 var->set_end(position()); 319 return var; 320 } 321 var->set_type(parse_type(var)); 322 auto name = parse_name(*var); 323 RefPtr<Expression const> initial_value; 324 325 if (match(Token::Type::Equals)) { 326 consume(Token::Type::Equals); 327 initial_value = parse_expression(var); 328 } 329 330 if (match_braced_init_list()) { 331 initial_value = parse_braced_init_list(var); 332 } 333 334 if (expect_semicolon) 335 consume(Token::Type::Semicolon); 336 337 var->set_end(position()); 338 var->set_name(name); 339 var->set_initial_value(move(initial_value)); 340 341 return var; 342} 343 344NonnullRefPtr<Expression const> Parser::parse_expression(ASTNode const& parent) 345{ 346 LOG_SCOPE(); 347 auto expression = parse_primary_expression(parent); 348 // TODO: remove eof() logic, should still work without it 349 if (eof() || match(Token::Type::Semicolon)) { 350 return expression; 351 } 352 353 Vector<NonnullRefPtr<Expression const>> secondary_expressions; 354 355 while (match_secondary_expression()) { 356 // FIXME: Handle operator precedence 357 expression = parse_secondary_expression(parent, expression); 358 secondary_expressions.append(expression); 359 } 360 361 for (size_t i = 0; secondary_expressions.size() != 0 && i < secondary_expressions.size() - 1; ++i) { 362 const_cast<Expression&>(*secondary_expressions[i]).set_parent(secondary_expressions[i + 1]); 363 } 364 365 return expression; 366} 367 368bool Parser::match_secondary_expression() 369{ 370 auto type = peek().type(); 371 return type == Token::Type::Plus 372 || type == Token::Type::PlusEquals 373 || type == Token::Type::Minus 374 || type == Token::Type::MinusEquals 375 || type == Token::Type::Asterisk 376 || type == Token::Type::AsteriskEquals 377 || type == Token::Type::Percent 378 || type == Token::Type::PercentEquals 379 || type == Token::Type::Equals 380 || type == Token::Type::Greater 381 || type == Token::Type::GreaterEquals 382 || type == Token::Type::Less 383 || type == Token::Type::LessEquals 384 || type == Token::Type::Dot 385 || type == Token::Type::PlusPlus 386 || type == Token::Type::MinusMinus 387 || type == Token::Type::And 388 || type == Token::Type::AndEquals 389 || type == Token::Type::Pipe 390 || type == Token::Type::PipeEquals 391 || type == Token::Type::Caret 392 || type == Token::Type::CaretEquals 393 || type == Token::Type::LessLess 394 || type == Token::Type::LessLessEquals 395 || type == Token::Type::GreaterGreater 396 || type == Token::Type::GreaterGreaterEquals 397 || type == Token::Type::EqualsEquals 398 || type == Token::Type::AndAnd 399 || type == Token::Type::PipePipe 400 || type == Token::Type::ExclamationMarkEquals 401 || type == Token::Type::Arrow 402 || type == Token::Type::LeftParen; 403} 404 405NonnullRefPtr<Expression const> Parser::parse_primary_expression(ASTNode const& parent) 406{ 407 LOG_SCOPE(); 408 // TODO: remove eof() logic, should still work without it 409 if (eof()) { 410 auto node = create_ast_node<Identifier>(parent, position(), position()); 411 return node; 412 } 413 414 if (match_unary_expression()) 415 return parse_unary_expression(parent); 416 417 if (match_literal()) { 418 return parse_literal(parent); 419 } 420 421 if (match_cpp_cast_expression()) 422 return parse_cpp_cast_expression(parent); 423 424 if (match_c_style_cast_expression()) 425 return parse_c_style_cast_expression(parent); 426 427 if (match_sizeof_expression()) 428 return parse_sizeof_expression(parent); 429 430 if (match_braced_init_list()) 431 return parse_braced_init_list(parent); 432 433 if (match_name()) { 434 return parse_name(parent); 435 } 436 437 error("could not parse primary expression"sv); 438 auto token = consume(); 439 return create_ast_node<InvalidExpression>(parent, token.start(), token.end()); 440} 441 442bool Parser::match_literal() 443{ 444 switch (peek().type()) { 445 case Token::Type::Integer: 446 return true; 447 case Token::Type::SingleQuotedString: 448 return true; 449 case Token::Type::DoubleQuotedString: 450 return true; 451 case Token::Type::Float: 452 return true; 453 case Token::Type::Keyword: { 454 return match_boolean_literal() || peek().text() == "nullptr"; 455 } 456 default: 457 return false; 458 } 459} 460 461bool Parser::match_unary_expression() 462{ 463 auto type = peek().type(); 464 return type == Token::Type::PlusPlus 465 || type == Token::Type::MinusMinus 466 || type == Token::Type::ExclamationMark 467 || type == Token::Type::Tilde 468 || type == Token::Type::Plus 469 || type == Token::Type::Minus 470 || type == Token::Type::And; 471} 472 473NonnullRefPtr<UnaryExpression const> Parser::parse_unary_expression(ASTNode const& parent) 474{ 475 auto unary_exp = create_ast_node<UnaryExpression>(parent, position(), {}); 476 auto op_token = consume(); 477 UnaryOp op { UnaryOp::Invalid }; 478 switch (op_token.type()) { 479 case Token::Type::Minus: 480 op = UnaryOp::Minus; 481 break; 482 case Token::Type::Plus: 483 op = UnaryOp::Plus; 484 break; 485 case Token::Type::ExclamationMark: 486 op = UnaryOp::Not; 487 break; 488 case Token::Type::Tilde: 489 op = UnaryOp::BitwiseNot; 490 break; 491 case Token::Type::PlusPlus: 492 op = UnaryOp::PlusPlus; 493 break; 494 case Token::Type::And: 495 op = UnaryOp::Address; 496 break; 497 default: 498 break; 499 } 500 unary_exp->set_op(op); 501 auto lhs = parse_expression(*unary_exp); 502 unary_exp->set_lhs(lhs); 503 unary_exp->set_end(lhs->end()); 504 return unary_exp; 505} 506 507NonnullRefPtr<Expression const> Parser::parse_literal(ASTNode const& parent) 508{ 509 switch (peek().type()) { 510 case Token::Type::Integer: { 511 auto token = consume(); 512 return create_ast_node<NumericLiteral>(parent, token.start(), token.end(), text_of_token(token)); 513 } 514 case Token::Type::SingleQuotedString: 515 [[fallthrough]]; 516 case Token::Type::DoubleQuotedString: 517 return parse_string_literal(parent); 518 case Token::Type::Keyword: { 519 if (match_boolean_literal()) 520 return parse_boolean_literal(parent); 521 if (peek().text() == "nullptr") { 522 auto token = consume(); 523 return create_ast_node<NullPointerLiteral>(parent, token.start(), token.end()); 524 } 525 [[fallthrough]]; 526 } 527 default: { 528 error("could not parse literal"sv); 529 auto token = consume(); 530 return create_ast_node<InvalidExpression>(parent, token.start(), token.end()); 531 } 532 } 533} 534 535NonnullRefPtr<Expression const> Parser::parse_secondary_expression(ASTNode const& parent, NonnullRefPtr<Expression const> lhs) 536{ 537 LOG_SCOPE(); 538 switch (peek().type()) { 539 case Token::Type::Plus: 540 return parse_binary_expression(parent, lhs, BinaryOp::Addition); 541 case Token::Type::Less: 542 return parse_binary_expression(parent, lhs, BinaryOp::LessThan); 543 case Token::Type::EqualsEquals: 544 return parse_binary_expression(parent, lhs, BinaryOp::EqualsEquals); 545 case Token::Type::ExclamationMarkEquals: 546 return parse_binary_expression(parent, lhs, BinaryOp::NotEqual); 547 case Token::Type::And: 548 return parse_binary_expression(parent, lhs, BinaryOp::BitwiseAnd); 549 case Token::Type::AndAnd: 550 return parse_binary_expression(parent, lhs, BinaryOp::LogicalAnd); 551 case Token::Type::Pipe: 552 return parse_binary_expression(parent, lhs, BinaryOp::BitwiseOr); 553 case Token::Type::PipePipe: 554 return parse_binary_expression(parent, lhs, BinaryOp::LogicalOr); 555 case Token::Type::Arrow: 556 return parse_binary_expression(parent, lhs, BinaryOp::Arrow); 557 case Token::Type::Equals: 558 return parse_assignment_expression(parent, lhs, AssignmentOp::Assignment); 559 case Token::Type::Dot: { 560 consume(); 561 auto exp = create_ast_node<MemberExpression>(parent, lhs->start(), {}); 562 const_cast<Expression&>(*lhs).set_parent(*exp); 563 exp->set_object(move(lhs)); 564 auto identifier_token = consume(Token::Type::Identifier); 565 exp->set_property(create_ast_node<Identifier>(*exp, identifier_token.start(), identifier_token.end(), identifier_token.text())); 566 exp->set_end(position()); 567 return exp; 568 } 569 case Token::Type::LeftParen: { 570 consume(); 571 auto func = create_ast_node<FunctionCall>(parent, lhs->start(), {}); 572 const_cast<Expression&>(*lhs).set_parent(*func); 573 func->set_callee(move(lhs)); 574 while (peek().type() != Token::Type::RightParen && !eof()) { 575 func->add_argument(parse_expression(*func)); 576 if (peek().type() == Token::Type::Comma) 577 consume(Token::Type::Comma); 578 } 579 consume(Token::Type::RightParen); 580 func->set_end(position()); 581 return func; 582 } 583 default: { 584 error(DeprecatedString::formatted("unexpected operator for expression. operator: {}", peek().to_deprecated_string())); 585 auto token = consume(); 586 return create_ast_node<InvalidExpression>(parent, token.start(), token.end()); 587 } 588 } 589} 590 591NonnullRefPtr<BinaryExpression const> Parser::parse_binary_expression(ASTNode const& parent, NonnullRefPtr<Expression const> lhs, BinaryOp op) 592{ 593 consume(); // Operator 594 auto exp = create_ast_node<BinaryExpression>(parent, lhs->start(), {}); 595 const_cast<Expression&>(*lhs).set_parent(*exp); 596 exp->set_op(op); 597 exp->set_lhs(move(lhs)); 598 auto rhs = parse_expression(exp); 599 exp->set_end(rhs->end()); 600 exp->set_rhs(move(rhs)); 601 return exp; 602} 603 604NonnullRefPtr<AssignmentExpression const> Parser::parse_assignment_expression(ASTNode const& parent, NonnullRefPtr<Expression const> lhs, AssignmentOp op) 605{ 606 consume(); // Operator 607 auto exp = create_ast_node<AssignmentExpression>(parent, lhs->start(), {}); 608 const_cast<Expression&>(*lhs).set_parent(*exp); 609 exp->set_op(op); 610 exp->set_lhs(move(lhs)); 611 auto rhs = parse_expression(exp); 612 exp->set_end(rhs->end()); 613 exp->set_rhs(move(rhs)); 614 return exp; 615} 616 617Optional<Parser::DeclarationType> Parser::match_declaration_in_translation_unit() 618{ 619 if (match_function_declaration()) 620 return DeclarationType::Function; 621 if (match_enum_declaration()) 622 return DeclarationType::Enum; 623 if (match_class_declaration()) 624 return DeclarationType::Class; 625 if (match_namespace_declaration()) 626 return DeclarationType::Namespace; 627 if (match_variable_declaration()) 628 return DeclarationType::Variable; 629 if (match_using_namespace_declaration()) 630 return DeclarationType::UsingNamespace; 631 return {}; 632} 633 634Optional<Parser::DeclarationType> Parser::match_class_member(StringView class_name) 635{ 636 if (match_function_declaration()) 637 return DeclarationType::Function; 638 if (match_enum_declaration()) 639 return DeclarationType::Enum; 640 if (match_class_declaration()) 641 return DeclarationType::Class; 642 if (match_variable_declaration()) 643 return DeclarationType::Variable; 644 if (match_constructor(class_name)) 645 return DeclarationType::Constructor; 646 if (match_destructor(class_name)) 647 return DeclarationType::Destructor; 648 return {}; 649} 650 651bool Parser::match_enum_declaration() 652{ 653 save_state(); 654 ScopeGuard state_guard = [this] { load_state(); }; 655 656 if (!match_keyword("enum")) 657 return false; 658 659 consume(Token::Type::Keyword); 660 661 if (match_keyword("class")) 662 consume(Token::Type::Keyword); 663 664 if (!match(Token::Type::Identifier)) 665 return false; 666 667 consume(Token::Type::Identifier); 668 669 return match(Token::Type::LeftCurly); 670} 671 672bool Parser::match_class_declaration() 673{ 674 save_state(); 675 ScopeGuard state_guard = [this] { load_state(); }; 676 677 if (!match_keyword("struct") && !match_keyword("class")) 678 return false; 679 680 consume(Token::Type::Keyword); 681 682 if (!match(Token::Type::Identifier)) 683 return false; 684 685 consume(Token::Type::Identifier); 686 687 auto has_final = match_keyword("final"); 688 689 if (peek(has_final ? 1 : 0).type() == Token::Type::Colon) { 690 if (has_final) 691 consume(); 692 693 do { 694 consume(); 695 696 while (match_keyword("private") || match_keyword("public") || match_keyword("protected") || match_keyword("virtual")) 697 consume(); 698 699 if (!match_name()) 700 return false; 701 (void)parse_name(get_dummy_node()); 702 } while (peek().type() == Token::Type::Comma); 703 } 704 705 return match(Token::Type::LeftCurly); 706} 707 708bool Parser::match_namespace_declaration() 709{ 710 return match_keyword("namespace"); 711} 712 713bool Parser::match_function_declaration() 714{ 715 save_state(); 716 ScopeGuard state_guard = [this] { load_state(); }; 717 718 parse_function_qualifiers(); 719 720 if (!match_type()) 721 return false; 722 723 VERIFY(m_root_node); 724 (void)parse_type(get_dummy_node()); 725 726 if (!match_name()) 727 return false; 728 729 (void)parse_name(get_dummy_node()); 730 731 if (!peek(Token::Type::LeftParen).has_value()) 732 return false; 733 consume(); 734 735 while (consume().type() != Token::Type::RightParen && !eof()) { }; 736 737 while (match_keyword("const") || match_keyword("override")) 738 consume(); 739 740 if (peek(Token::Type::Semicolon).has_value() || peek(Token::Type::LeftCurly).has_value()) 741 return true; 742 743 if (match_attribute_specification()) { 744 consume_attribute_specification(); 745 return peek(Token::Type::Semicolon).has_value(); 746 } 747 748 return false; 749} 750 751Optional<Vector<NonnullRefPtr<Parameter const>>> Parser::parse_parameter_list(ASTNode const& parent) 752{ 753 LOG_SCOPE(); 754 Vector<NonnullRefPtr<Parameter const>> parameters; 755 while (peek().type() != Token::Type::RightParen && !eof()) { 756 if (match_ellipsis()) { 757 auto param = create_ast_node<Parameter>(parent, position(), {}, RefPtr<Name> {}); 758 consume(Token::Type::Dot); 759 consume(Token::Type::Dot); 760 auto last_dot = consume(Token::Type::Dot); 761 param->set_ellipsis(true); 762 param->set_end(last_dot.end()); 763 parameters.append(move(param)); 764 } else { 765 auto type = parse_type(parent); 766 767 RefPtr<Name const> name; 768 if (match_name()) { 769 name = parse_name(parent); 770 } 771 772 auto param = create_ast_node<Parameter>(parent, type->start(), !name.is_null() ? name->end() : type->end(), name); 773 const_cast<Type&>(*type).set_parent(*param.ptr()); 774 775 param->set_type(move(type)); 776 parameters.append(move(param)); 777 } 778 779 if (peek(Token::Type::Comma).has_value()) 780 consume(Token::Type::Comma); 781 } 782 return parameters; 783} 784 785bool Parser::match_comment() 786{ 787 return match(Token::Type::Comment); 788} 789 790bool Parser::match_whitespace() 791{ 792 return match(Token::Type::Whitespace); 793} 794 795bool Parser::match_preprocessor() 796{ 797 return match(Token::Type::PreprocessorStatement) || match(Token::Type::IncludeStatement); 798} 799 800void Parser::consume_preprocessor() 801{ 802 LOG_SCOPE(); 803 switch (peek().type()) { 804 case Token::Type::PreprocessorStatement: 805 consume(); 806 break; 807 case Token::Type::IncludeStatement: 808 consume(); 809 consume(Token::Type::IncludePath); 810 break; 811 default: 812 error("unexpected token while parsing preprocessor statement"sv); 813 consume(); 814 } 815} 816 817Optional<Token> Parser::consume_whitespace() 818{ 819 LOG_SCOPE(); 820 return consume(Token::Type::Whitespace); 821} 822 823Token Parser::consume(Token::Type type) 824{ 825 auto token = consume(); 826 if (token.type() != type) 827 error(DeprecatedString::formatted("expected {} at {}:{}, found: {}", Token::type_to_string(type), token.start().line, token.start().column, Token::type_to_string(token.type()))); 828 return token; 829} 830 831bool Parser::match(Token::Type type) 832{ 833 return peek().type() == type; 834} 835 836Token Parser::consume() 837{ 838 if (eof()) { 839 error("C++ Parser: out of tokens"sv); 840 return { Token::Type::EOF_TOKEN, position(), position(), {} }; 841 } 842 return m_tokens[m_state.token_index++]; 843} 844 845Token Parser::peek(size_t offset) const 846{ 847 if (m_state.token_index + offset >= m_tokens.size()) 848 return { Token::Type::EOF_TOKEN, position(), position(), {} }; 849 return m_tokens[m_state.token_index + offset]; 850} 851 852Optional<Token> Parser::peek(Token::Type type) const 853{ 854 auto token = peek(); 855 if (token.type() == type) 856 return token; 857 return {}; 858} 859 860void Parser::save_state() 861{ 862 m_saved_states.append(m_state); 863 m_state.state_nodes.clear(); 864} 865 866void Parser::load_state() 867{ 868 m_state = m_saved_states.take_last(); 869} 870 871StringView Parser::text_of_token(Cpp::Token const& token) const 872{ 873 return token.text(); 874} 875 876DeprecatedString Parser::text_of_node(ASTNode const& node) const 877{ 878 return text_in_range(node.start(), node.end()); 879} 880 881DeprecatedString Parser::text_in_range(Position start, Position end) const 882{ 883 StringBuilder builder; 884 for (auto token : tokens_in_range(start, end)) { 885 builder.append(token.text()); 886 } 887 return builder.to_deprecated_string(); 888} 889 890Vector<Token> Parser::tokens_in_range(Position start, Position end) const 891{ 892 auto start_token_index = index_of_token_at(start); 893 auto end_node_index = index_of_token_at(end); 894 VERIFY(start_token_index.has_value()); 895 VERIFY(end_node_index.has_value()); 896 897 Vector<Token> tokens; 898 for (size_t i = start_token_index.value(); i <= end_node_index.value(); ++i) { 899 tokens.append(m_tokens[i]); 900 } 901 return tokens; 902} 903 904void Parser::error(StringView message) 905{ 906 LOG_SCOPE(); 907 908 if (!m_saved_states.is_empty()) 909 return; 910 911 if (message.is_null() || message.is_empty()) 912 message = "<empty>"sv; 913 DeprecatedString formatted_message; 914 if (m_state.token_index >= m_tokens.size()) { 915 formatted_message = DeprecatedString::formatted("C++ Parsed error on EOF.{}", message); 916 } else { 917 formatted_message = DeprecatedString::formatted("C++ Parser error: {}. token: {} ({}:{})", 918 message, 919 m_state.token_index < m_tokens.size() ? text_of_token(m_tokens[m_state.token_index]) : "EOF"sv, 920 m_tokens[m_state.token_index].start().line, 921 m_tokens[m_state.token_index].start().column); 922 } 923 924 m_errors.append(formatted_message); 925} 926 927bool Parser::match_expression() 928{ 929 return match_literal() 930 || match_name() 931 || match_unary_expression() 932 || match_cpp_cast_expression() 933 || match_c_style_cast_expression() 934 || match_sizeof_expression() 935 || match_braced_init_list(); 936} 937 938bool Parser::eof() const 939{ 940 return m_state.token_index >= m_tokens.size(); 941} 942 943Position Parser::position() const 944{ 945 if (m_tokens.is_empty()) 946 return {}; 947 948 if (eof()) 949 return m_tokens.last().end(); 950 951 return peek().start(); 952} 953 954Position Parser::previous_token_end() const 955{ 956 if (m_state.token_index < 1) 957 return {}; 958 return m_tokens[m_state.token_index - 1].end(); 959} 960 961RefPtr<ASTNode const> Parser::node_at(Position pos) const 962{ 963 VERIFY(m_saved_states.is_empty()); 964 auto index = index_of_node_at(pos); 965 if (!index.has_value()) 966 return nullptr; 967 return m_nodes[index.value()]; 968} 969 970Optional<size_t> Parser::index_of_node_at(Position pos) const 971{ 972 VERIFY(!m_tokens.is_empty()); 973 VERIFY(m_saved_states.is_empty()); 974 Optional<size_t> match_node_index; 975 976 auto node_span = [](ASTNode const& node) { 977 VERIFY(node.end().line >= node.start().line); 978 VERIFY((node.end().line > node.start().line) || (node.end().column >= node.start().column)); 979 return Position { node.end().line - node.start().line, node.start().line != node.end().line ? 0 : node.end().column - node.start().column }; 980 }; 981 982 for (size_t node_index = 0; node_index < m_nodes.size(); ++node_index) { 983 auto& node = m_nodes[node_index]; 984 if (node->start() > pos || node->end() < pos) 985 continue; 986 987 if (!match_node_index.has_value() || (node_span(node) <= node_span(m_nodes[match_node_index.value()]))) 988 match_node_index = node_index; 989 } 990 return match_node_index; 991} 992 993Optional<Token> Parser::token_at(Position pos) const 994{ 995 auto index = index_of_token_at(pos); 996 if (!index.has_value()) 997 return {}; 998 return m_tokens[index.value()]; 999} 1000 1001Optional<size_t> Parser::index_of_token_at(Position pos) const 1002{ 1003 for (size_t token_index = 0; token_index < m_tokens.size(); ++token_index) { 1004 auto token = m_tokens[token_index]; 1005 if (token.start() > pos || token.end() < pos) 1006 continue; 1007 return token_index; 1008 } 1009 return {}; 1010} 1011 1012void Parser::print_tokens() const 1013{ 1014 for (auto& token : m_tokens) { 1015 outln("{}", token.to_deprecated_string()); 1016 } 1017} 1018 1019Vector<CodeComprehension::TodoEntry> Parser::get_todo_entries() const 1020{ 1021 Vector<CodeComprehension::TodoEntry> ret; 1022 for (auto& token : m_tokens) { 1023 if (token.type() == Token::Type::Comment) { 1024 if (token.text().contains("TODO"sv) || token.text().contains("FIXME"sv)) { 1025 ret.append({ token.text(), m_filename, token.start().line, token.start().column }); 1026 } 1027 } 1028 } 1029 return ret; 1030} 1031 1032NonnullRefPtr<StringLiteral const> Parser::parse_string_literal(ASTNode const& parent) 1033{ 1034 LOG_SCOPE(); 1035 Optional<size_t> start_token_index; 1036 Optional<size_t> end_token_index; 1037 while (!eof()) { 1038 auto token = peek(); 1039 if (token.type() != Token::Type::DoubleQuotedString && token.type() != Token::Type::SingleQuotedString && token.type() != Token::Type::EscapeSequence) { 1040 VERIFY(start_token_index.has_value()); 1041 end_token_index = m_state.token_index - 1; 1042 break; 1043 } 1044 if (!start_token_index.has_value()) 1045 start_token_index = m_state.token_index; 1046 consume(); 1047 } 1048 1049 // String was not terminated 1050 if (!end_token_index.has_value()) { 1051 end_token_index = m_tokens.size() - 1; 1052 } 1053 1054 VERIFY(start_token_index.has_value()); 1055 VERIFY(end_token_index.has_value()); 1056 1057 Token start_token = m_tokens[start_token_index.value()]; 1058 Token end_token = m_tokens[end_token_index.value()]; 1059 1060 auto text = text_in_range(start_token.start(), end_token.end()); 1061 auto string_literal = create_ast_node<StringLiteral>(parent, start_token.start(), end_token.end()); 1062 string_literal->set_value(move(text)); 1063 return string_literal; 1064} 1065 1066NonnullRefPtr<ReturnStatement const> Parser::parse_return_statement(ASTNode const& parent) 1067{ 1068 LOG_SCOPE(); 1069 auto return_statement = create_ast_node<ReturnStatement>(parent, position(), {}); 1070 consume(Token::Type::Keyword); 1071 if (!peek(Token::Type::Semicolon).has_value()) { 1072 return_statement->set_value(parse_expression(*return_statement)); 1073 } 1074 return_statement->set_end(position()); 1075 return return_statement; 1076} 1077 1078NonnullRefPtr<EnumDeclaration const> Parser::parse_enum_declaration(ASTNode const& parent) 1079{ 1080 LOG_SCOPE(); 1081 auto enum_decl = create_ast_node<EnumDeclaration>(parent, position(), {}); 1082 consume_keyword("enum"); 1083 1084 if (match_keyword("class")) { 1085 consume(Token::Type::Keyword); 1086 enum_decl->set_type(EnumDeclaration::Type::EnumClass); 1087 } else { 1088 enum_decl->set_type(EnumDeclaration::Type::RegularEnum); 1089 } 1090 1091 auto name = parse_name(*enum_decl); 1092 enum_decl->set_name(name); 1093 consume(Token::Type::LeftCurly); 1094 while (!eof() && peek().type() != Token::Type::RightCurly) { 1095 auto name = text_of_token(consume(Token::Type::Identifier)); 1096 RefPtr<Expression const> value; 1097 if (peek().type() == Token::Type::Equals) { 1098 consume(); 1099 value = parse_expression(enum_decl); 1100 } 1101 enum_decl->add_entry(name, move(value)); 1102 if (peek().type() != Token::Type::Comma) { 1103 break; 1104 } 1105 consume(Token::Type::Comma); 1106 } 1107 consume(Token::Type::RightCurly); 1108 consume(Token::Type::Semicolon); 1109 enum_decl->set_end(position()); 1110 return enum_decl; 1111} 1112 1113Token Parser::consume_keyword(DeprecatedString const& keyword) 1114{ 1115 auto token = consume(); 1116 if (token.type() != Token::Type::Keyword) { 1117 error(DeprecatedString::formatted("unexpected token: {}, expected Keyword", token.to_deprecated_string())); 1118 return token; 1119 } 1120 if (text_of_token(token) != keyword) { 1121 error(DeprecatedString::formatted("unexpected keyword: {}, expected {}", text_of_token(token), keyword)); 1122 return token; 1123 } 1124 return token; 1125} 1126 1127bool Parser::match_keyword(DeprecatedString const& keyword) 1128{ 1129 auto token = peek(); 1130 if (token.type() != Token::Type::Keyword) { 1131 return false; 1132 } 1133 if (text_of_token(token) != keyword) { 1134 return false; 1135 } 1136 return true; 1137} 1138 1139NonnullRefPtr<StructOrClassDeclaration const> Parser::parse_class_declaration(ASTNode const& parent) 1140{ 1141 LOG_SCOPE(); 1142 1143 auto type_token = consume(Token::Type::Keyword); 1144 StructOrClassDeclaration::Type type {}; 1145 1146 if (type_token.text() == "struct") 1147 type = StructOrClassDeclaration::Type::Struct; 1148 if (type_token.text() == "class") 1149 type = StructOrClassDeclaration::Type::Class; 1150 1151 auto decl = create_ast_node<StructOrClassDeclaration>(parent, position(), {}, type); 1152 1153 auto name = parse_name(*decl); 1154 decl->set_name(name); 1155 1156 auto has_final = match_keyword("final"); 1157 1158 Vector<NonnullRefPtr<Name const>> baseclasses; 1159 1160 // FIXME: Don't ignore this. 1161 if (peek(has_final ? 1 : 0).type() == Token::Type::Colon) { 1162 if (has_final) 1163 consume(); 1164 1165 do { 1166 consume(); 1167 1168 while (match_keyword("private") || match_keyword("public") || match_keyword("protected") || match_keyword("virtual")) 1169 consume(); 1170 1171 baseclasses.append(parse_name(*decl)); 1172 } while (peek().type() == Token::Type::Comma); 1173 } 1174 1175 decl->set_baseclasses(move(baseclasses)); 1176 1177 consume(Token::Type::LeftCurly); 1178 1179 while (!eof() && peek().type() != Token::Type::RightCurly) { 1180 decl->set_members(parse_class_members(*decl)); 1181 } 1182 1183 consume(Token::Type::RightCurly); 1184 consume(Token::Type::Semicolon); 1185 decl->set_end(position()); 1186 return decl; 1187} 1188 1189NonnullRefPtr<BooleanLiteral const> Parser::parse_boolean_literal(ASTNode const& parent) 1190{ 1191 LOG_SCOPE(); 1192 auto token = consume(Token::Type::Keyword); 1193 auto text = text_of_token(token); 1194 // text == "true" || text == "false"; 1195 bool value = (text == "true"); 1196 return create_ast_node<BooleanLiteral>(parent, token.start(), token.end(), value); 1197} 1198 1199bool Parser::match_boolean_literal() 1200{ 1201 auto token = peek(); 1202 if (token.type() != Token::Type::Keyword) 1203 return false; 1204 auto text = text_of_token(token); 1205 return text == "true" || text == "false"; 1206} 1207 1208NonnullRefPtr<Type const> Parser::parse_type(ASTNode const& parent) 1209{ 1210 LOG_SCOPE(); 1211 1212 if (!match_named_type()) { 1213 error("expected named named_type"sv); 1214 auto token = consume(); 1215 return create_ast_node<NamedType>(parent, token.start(), token.end()); 1216 } 1217 1218 auto named_type = create_ast_node<NamedType>(parent, position(), {}); 1219 1220 auto qualifiers = parse_type_qualifiers(); 1221 named_type->set_qualifiers(move(qualifiers)); 1222 1223 if (match_keyword("auto")) { 1224 consume(Token::Type::Keyword); 1225 named_type->set_auto(true); 1226 auto original_qualifiers = named_type->qualifiers(); 1227 original_qualifiers.extend(parse_type_qualifiers()); 1228 named_type->set_qualifiers(move(original_qualifiers)); 1229 named_type->set_end(position()); 1230 return named_type; 1231 } 1232 1233 if (match_keyword("struct")) { 1234 consume(Token::Type::Keyword); // Consume struct prefix 1235 } 1236 1237 if (!match_name()) { 1238 named_type->set_end(position()); 1239 error(DeprecatedString::formatted("expected name instead of: {}", peek().text())); 1240 return named_type; 1241 } 1242 named_type->set_name(parse_name(*named_type)); 1243 1244 auto original_qualifiers = named_type->qualifiers(); 1245 original_qualifiers.extend(parse_type_qualifiers()); 1246 named_type->set_qualifiers(move(original_qualifiers)); 1247 1248 NonnullRefPtr<Type> type = named_type; 1249 while (!eof() && peek().type() == Token::Type::Asterisk) { 1250 type->set_end(position()); 1251 auto asterisk = consume(); 1252 auto ptr = create_ast_node<Pointer>(parent, type->start(), asterisk.end()); 1253 type->set_parent(*ptr); 1254 ptr->set_pointee(type); 1255 ptr->set_qualifiers(parse_type_qualifiers()); 1256 ptr->set_end(position()); 1257 type = ptr; 1258 } 1259 1260 if (!eof() && (peek().type() == Token::Type::And || peek().type() == Token::Type::AndAnd)) { 1261 type->set_end(position()); 1262 auto ref_token = consume(); 1263 auto ref = create_ast_node<Reference>(parent, type->start(), ref_token.end(), ref_token.type() == Token::Type::And ? Reference::Kind::Lvalue : Reference::Kind::Rvalue); 1264 type->set_parent(*ref); 1265 ref->set_referenced_type(type); 1266 ref->set_end(position()); 1267 type = ref; 1268 } 1269 1270 if (peek().type() == Token::Type::LeftParen) { 1271 type->set_end(previous_token_end()); 1272 consume(); 1273 auto fn_type = create_ast_node<FunctionType>(parent, type->start(), position()); 1274 fn_type->set_return_type(*type); 1275 type->set_parent(*fn_type); 1276 if (auto parameters = parse_parameter_list(*type); parameters.has_value()) 1277 fn_type->set_parameters(parameters.release_value()); 1278 consume(Token::Type::RightParen); 1279 type = fn_type; 1280 } 1281 1282 type->set_end(previous_token_end()); 1283 1284 return type; 1285} 1286 1287NonnullRefPtr<ForStatement const> Parser::parse_for_statement(ASTNode const& parent) 1288{ 1289 LOG_SCOPE(); 1290 auto for_statement = create_ast_node<ForStatement>(parent, position(), {}); 1291 consume(Token::Type::Keyword); 1292 consume(Token::Type::LeftParen); 1293 if (peek().type() != Token::Type::Semicolon) 1294 for_statement->set_init(parse_variable_declaration(*for_statement, false)); 1295 consume(Token::Type::Semicolon); 1296 1297 if (peek().type() != Token::Type::Semicolon) 1298 for_statement->set_test(parse_expression(*for_statement)); 1299 consume(Token::Type::Semicolon); 1300 1301 if (peek().type() != Token::Type::RightParen) 1302 for_statement->set_update(parse_expression(*for_statement)); 1303 consume(Token::Type::RightParen); 1304 1305 for_statement->set_body(parse_statement(*for_statement)); 1306 1307 for_statement->set_end(for_statement->body()->end()); 1308 return for_statement; 1309} 1310 1311NonnullRefPtr<IfStatement const> Parser::parse_if_statement(ASTNode const& parent) 1312{ 1313 LOG_SCOPE(); 1314 auto if_statement = create_ast_node<IfStatement>(parent, position(), {}); 1315 consume(Token::Type::Keyword); 1316 consume(Token::Type::LeftParen); 1317 if_statement->set_predicate(parse_expression(*if_statement)); 1318 consume(Token::Type::RightParen); 1319 if_statement->set_then_statement(parse_statement(*if_statement)); 1320 if (match_keyword("else")) { 1321 consume(Token::Type::Keyword); 1322 if_statement->set_else_statement(parse_statement(*if_statement)); 1323 if_statement->set_end(if_statement->else_statement()->end()); 1324 } else { 1325 if_statement->set_end(if_statement->then_statement()->end()); 1326 } 1327 return if_statement; 1328} 1329Vector<StringView> Parser::parse_type_qualifiers() 1330{ 1331 LOG_SCOPE(); 1332 Vector<StringView> qualifiers; 1333 while (!eof()) { 1334 auto token = peek(); 1335 if (token.type() != Token::Type::Keyword) 1336 break; 1337 auto text = text_of_token(token); 1338 if (text == "static" || text == "const" || text == "extern") { 1339 qualifiers.append(text); 1340 consume(); 1341 } else { 1342 break; 1343 } 1344 } 1345 return qualifiers; 1346} 1347 1348Vector<StringView> Parser::parse_function_qualifiers() 1349{ 1350 LOG_SCOPE(); 1351 Vector<StringView> qualifiers; 1352 while (!eof()) { 1353 auto token = peek(); 1354 if (token.type() != Token::Type::Keyword) 1355 break; 1356 auto text = text_of_token(token); 1357 if (text == "static" || text == "inline" || text == "extern" || text == "virtual") { 1358 qualifiers.append(text); 1359 consume(); 1360 } else { 1361 break; 1362 } 1363 } 1364 return qualifiers; 1365} 1366 1367bool Parser::match_attribute_specification() 1368{ 1369 return text_of_token(peek()) == "__attribute__"; 1370} 1371void Parser::consume_attribute_specification() 1372{ 1373 consume(); // __attribute__ 1374 consume(Token::Type::LeftParen); 1375 size_t left_count = 1; 1376 while (!eof()) { 1377 auto token = consume(); 1378 if (token.type() == Token::Type::LeftParen) { 1379 ++left_count; 1380 } 1381 if (token.type() == Token::Type::RightParen) { 1382 --left_count; 1383 } 1384 if (left_count == 0) 1385 return; 1386 } 1387} 1388 1389bool Parser::match_ellipsis() 1390{ 1391 if (m_state.token_index > m_tokens.size() - 3) 1392 return false; 1393 return peek().type() == Token::Type::Dot && peek(1).type() == Token::Type::Dot && peek(2).type() == Token::Type::Dot; 1394} 1395 1396NonnullRefPtr<NamespaceDeclaration const> Parser::parse_namespace_declaration(ASTNode const& parent, bool is_nested_namespace) 1397{ 1398 auto namespace_decl = create_ast_node<NamespaceDeclaration>(parent, position(), {}); 1399 1400 if (!is_nested_namespace) 1401 consume(Token::Type::Keyword); 1402 1403 auto name = parse_name(*namespace_decl); 1404 namespace_decl->set_name(name); 1405 1406 if (peek().type() == Token::Type::ColonColon) { 1407 consume(Token::Type::ColonColon); 1408 namespace_decl->add_declaration(parse_namespace_declaration(*namespace_decl, true)); 1409 namespace_decl->set_end(position()); 1410 return namespace_decl; 1411 } 1412 1413 consume(Token::Type::LeftCurly); 1414 while (!eof() && peek().type() != Token::Type::RightCurly) { 1415 auto declaration = parse_single_declaration_in_translation_unit(*namespace_decl); 1416 if (declaration) { 1417 namespace_decl->add_declaration(declaration.release_nonnull()); 1418 } else { 1419 error("unexpected token"sv); 1420 consume(); 1421 } 1422 } 1423 consume(Token::Type::RightCurly); 1424 namespace_decl->set_end(position()); 1425 return namespace_decl; 1426} 1427 1428bool Parser::match_name() 1429{ 1430 auto type = peek().type(); 1431 return type == Token::Type::Identifier || type == Token::Type::KnownType; 1432} 1433 1434NonnullRefPtr<Name const> Parser::parse_name(ASTNode const& parent) 1435{ 1436 LOG_SCOPE(); 1437 NonnullRefPtr<Name> name_node = create_ast_node<Name>(parent, position(), {}); 1438 while (!eof() && (peek().type() == Token::Type::Identifier || peek().type() == Token::Type::KnownType) && peek(1).type() == Token::Type::ColonColon) { 1439 auto token = consume(); 1440 name_node->add_to_scope(create_ast_node<Identifier>(*name_node, token.start(), token.end(), token.text())); 1441 consume(Token::Type::ColonColon); 1442 } 1443 1444 if (peek().type() == Token::Type::Identifier || peek().type() == Token::Type::KnownType) { 1445 auto token = consume(); 1446 name_node->set_name(create_ast_node<Identifier>(*name_node, token.start(), token.end(), token.text())); 1447 } else { 1448 name_node->set_end(position()); 1449 return name_node; 1450 } 1451 1452 if (match_template_arguments()) { 1453 consume(Token::Type::Less); 1454 NonnullRefPtr<TemplatizedName> templatized_name = create_ast_node<TemplatizedName>(parent, name_node->start(), {}); 1455 templatized_name->set_name(name_node->name()); 1456 templatized_name->set_scope(name_node->scope()); 1457 name_node->set_end(position()); 1458 name_node = templatized_name; 1459 while (peek().type() != Token::Type::Greater && !eof()) { 1460 templatized_name->add_template_argument(parse_type(*templatized_name)); 1461 if (peek().type() == Token::Type::Comma) 1462 consume(Token::Type::Comma); 1463 } 1464 consume(Token::Type::Greater); 1465 } 1466 1467 name_node->set_end(previous_token_end()); 1468 return name_node; 1469} 1470 1471bool Parser::match_cpp_cast_expression() 1472{ 1473 save_state(); 1474 ScopeGuard state_guard = [this] { load_state(); }; 1475 1476 auto token = consume(); 1477 if (token.type() != Token::Type::Keyword) 1478 return false; 1479 1480 auto text = token.text(); 1481 if (text == "static_cast" || text == "reinterpret_cast" || text == "dynamic_cast" || text == "const_cast") 1482 return true; 1483 return false; 1484} 1485 1486bool Parser::match_c_style_cast_expression() 1487{ 1488 save_state(); 1489 ScopeGuard state_guard = [this] { load_state(); }; 1490 1491 if (consume().type() != Token::Type::LeftParen) 1492 return false; 1493 1494 if (!match_type()) 1495 return false; 1496 (void)parse_type(get_dummy_node()); 1497 1498 if (consume().type() != Token::Type::RightParen) 1499 return false; 1500 1501 if (!match_expression()) 1502 return false; 1503 1504 return true; 1505} 1506 1507NonnullRefPtr<CStyleCastExpression const> Parser::parse_c_style_cast_expression(ASTNode const& parent) 1508{ 1509 auto parse_exp = create_ast_node<CStyleCastExpression>(parent, position(), {}); 1510 1511 consume(Token::Type::LeftParen); 1512 parse_exp->set_type(parse_type(*parse_exp)); 1513 consume(Token::Type::RightParen); 1514 parse_exp->set_expression(parse_expression(*parse_exp)); 1515 parse_exp->set_end(position()); 1516 1517 return parse_exp; 1518} 1519 1520NonnullRefPtr<CppCastExpression const> Parser::parse_cpp_cast_expression(ASTNode const& parent) 1521{ 1522 auto cast_expression = create_ast_node<CppCastExpression>(parent, position(), {}); 1523 1524 cast_expression->set_cast_type(consume(Token::Type::Keyword).text()); 1525 1526 consume(Token::Type::Less); 1527 cast_expression->set_type(parse_type(*cast_expression)); 1528 consume(Token::Type::Greater); 1529 1530 consume(Token::Type::LeftParen); 1531 cast_expression->set_expression(parse_expression(*cast_expression)); 1532 consume(Token::Type::RightParen); 1533 1534 cast_expression->set_end(position()); 1535 1536 return cast_expression; 1537} 1538 1539bool Parser::match_sizeof_expression() 1540{ 1541 return match_keyword("sizeof"); 1542} 1543 1544NonnullRefPtr<SizeofExpression const> Parser::parse_sizeof_expression(ASTNode const& parent) 1545{ 1546 auto exp = create_ast_node<SizeofExpression>(parent, position(), {}); 1547 consume(Token::Type::Keyword); 1548 consume(Token::Type::LeftParen); 1549 exp->set_type(parse_type(parent)); 1550 consume(Token::Type::RightParen); 1551 exp->set_end(position()); 1552 return exp; 1553} 1554 1555bool Parser::match_braced_init_list() 1556{ 1557 return match(Token::Type::LeftCurly); 1558} 1559 1560NonnullRefPtr<BracedInitList const> Parser::parse_braced_init_list(ASTNode const& parent) 1561{ 1562 auto init_list = create_ast_node<BracedInitList>(parent, position(), {}); 1563 1564 consume(Token::Type::LeftCurly); 1565 while (!eof() && peek().type() != Token::Type::RightCurly) { 1566 init_list->add_expression(parse_expression(*init_list)); 1567 } 1568 consume(Token::Type::RightCurly); 1569 init_list->set_end(position()); 1570 return init_list; 1571} 1572Vector<NonnullRefPtr<Declaration const>> Parser::parse_class_members(StructOrClassDeclaration& parent) 1573{ 1574 auto class_name = parent.full_name(); 1575 1576 Vector<NonnullRefPtr<Declaration const>> members; 1577 while (!eof() && peek().type() != Token::Type::RightCurly) { 1578 if (match_access_specifier()) 1579 consume_access_specifier(); // FIXME: Do not ignore access specifiers 1580 auto member_type = match_class_member(class_name); 1581 if (member_type.has_value()) { 1582 members.append(parse_declaration(parent, member_type.value())); 1583 } else { 1584 error("Expected class member"sv); 1585 consume(); 1586 } 1587 } 1588 return members; 1589} 1590 1591bool Parser::match_access_specifier() 1592{ 1593 if (peek(1).type() != Token::Type::Colon) 1594 return false; 1595 1596 return match_keyword("private") || match_keyword("protected") || match_keyword("public"); 1597} 1598 1599void Parser::consume_access_specifier() 1600{ 1601 consume(Token::Type::Keyword); 1602 consume(Token::Type::Colon); 1603} 1604 1605bool Parser::match_constructor(StringView class_name) 1606{ 1607 save_state(); 1608 ScopeGuard state_guard = [this] { load_state(); }; 1609 1610 auto token = consume(); 1611 if (token.text() != class_name) 1612 return false; 1613 1614 if (!peek(Token::Type::LeftParen).has_value()) 1615 return false; 1616 consume(); 1617 1618 while (consume().type() != Token::Type::RightParen && !eof()) { }; 1619 1620 return (peek(Token::Type::Semicolon).has_value() || peek(Token::Type::LeftCurly).has_value()); 1621} 1622 1623bool Parser::match_destructor(StringView class_name) 1624{ 1625 save_state(); 1626 ScopeGuard state_guard = [this] { load_state(); }; 1627 1628 if (match_keyword("virtual")) 1629 consume(); 1630 1631 if (!match(Token::Type::Tilde)) 1632 return false; 1633 consume(); 1634 1635 auto token = peek(); 1636 1637 if (token.text() != class_name) 1638 return false; 1639 consume(); 1640 1641 if (!peek(Token::Type::LeftParen).has_value()) 1642 return false; 1643 consume(); 1644 1645 while (consume().type() != Token::Type::RightParen && !eof()) { }; 1646 1647 if (match_keyword("override")) 1648 consume(); 1649 1650 return (peek(Token::Type::Semicolon).has_value() || peek(Token::Type::LeftCurly).has_value()); 1651} 1652 1653void Parser::parse_constructor_or_destructor_impl(FunctionDeclaration& func, CtorOrDtor type) 1654{ 1655 if (type == CtorOrDtor::Dtor) { 1656 if (match_keyword("virtual")) 1657 func.set_qualifiers({ consume().text() }); 1658 consume(Token::Type::Tilde); 1659 } 1660 1661 auto name = parse_name(func); 1662 func.set_name(name); 1663 1664 consume(Token::Type::LeftParen); 1665 auto parameters = parse_parameter_list(func); 1666 if (parameters.has_value()) { 1667 if (type == CtorOrDtor::Dtor && !parameters->is_empty()) 1668 error("Destructor declaration that takes parameters"sv); 1669 else 1670 func.set_parameters(parameters.value()); 1671 } 1672 1673 consume(Token::Type::RightParen); 1674 1675 if (type == CtorOrDtor::Dtor && match_keyword("override")) 1676 consume(); 1677 1678 // TODO: Parse =default, =delete. 1679 1680 RefPtr<FunctionDefinition const> body; 1681 Position ctor_end {}; 1682 if (peek(Token::Type::LeftCurly).has_value()) { 1683 body = parse_function_definition(func); 1684 ctor_end = body->end(); 1685 } else { 1686 ctor_end = position(); 1687 if (match_attribute_specification()) 1688 consume_attribute_specification(); // we don't use the value of __attribute__ 1689 consume(Token::Type::Semicolon); 1690 } 1691 1692 func.set_definition(move(body)); 1693 func.set_end(ctor_end); 1694} 1695 1696NonnullRefPtr<Constructor const> Parser::parse_constructor(ASTNode const& parent) 1697{ 1698 auto ctor = create_ast_node<Constructor>(parent, position(), {}); 1699 parse_constructor_or_destructor_impl(*ctor, CtorOrDtor::Ctor); 1700 return ctor; 1701} 1702 1703NonnullRefPtr<Destructor const> Parser::parse_destructor(ASTNode const& parent) 1704{ 1705 auto ctor = create_ast_node<Destructor>(parent, position(), {}); 1706 parse_constructor_or_destructor_impl(*ctor, CtorOrDtor::Dtor); 1707 return ctor; 1708} 1709 1710bool Parser::match_using_namespace_declaration() 1711{ 1712 save_state(); 1713 ScopeGuard state_guard = [this] { load_state(); }; 1714 1715 if (!match_keyword("using")) 1716 return false; 1717 consume(); 1718 1719 if (!match_keyword("namespace")) 1720 return false; 1721 consume(); 1722 1723 return true; 1724} 1725 1726NonnullRefPtr<UsingNamespaceDeclaration const> Parser::parse_using_namespace_declaration(ASTNode const& parent) 1727{ 1728 auto decl = create_ast_node<UsingNamespaceDeclaration>(parent, position(), {}); 1729 1730 consume_keyword("using"); 1731 consume_keyword("namespace"); 1732 1733 auto name = parse_name(*decl); 1734 1735 decl->set_end(position()); 1736 consume(Token::Type::Semicolon); 1737 1738 decl->set_name(name); 1739 1740 return decl; 1741} 1742 1743}