1/* 2 * Copyright (c) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "parser/parser.h" 17#include <cstdio> 18#include "ast/ast_array_type.h" 19#include "ast/ast_list_type.h" 20#include "ast/ast_map_type.h" 21#include "ast/ast_parameter.h" 22#include "ast/ast_sequenceable_type.h" 23#include "util/logger.h" 24#include "util/string_builder.h" 25 26namespace OHOS { 27namespace Idl { 28const char* Parser::tag = "Parser"; 29 30Parser::Parser(const Options& options) 31 : options_(options) 32{} 33 34bool Parser::Parse(const String& sourceFile) 35{ 36 bool ret = lexer_.OpenSourceFile(sourceFile); 37 if (!ret) { 38 Logger::E(tag, "Fail to open file \"%s\".", sourceFile.string()); 39 return false; 40 } 41 ret = ParseFile(); 42 ret = CheckIntegrity() && ret; 43 if (!ret) { 44 ShowError(); 45 return false; 46 } 47 if (options_.DoDumpAST()) { 48 String astStr = module_->Dump(""); 49 printf("%s\n", astStr.string()); 50 } 51 return ret; 52} 53 54bool Parser::ParseFile() 55{ 56 bool ret = true; 57 58 module_ = new ASTModule(); 59 module_->SetIdlFile(lexer_.GetSourceFile()->GetPath()); 60 61 ParseLicense(); 62 63 Token token; 64 while ((token = lexer_.PeekToken()) != Token::END_OF_FILE) { 65 switch (token) { 66 case Token::BRACKETS_LEFT: 67 case Token::INTERFACE: 68 ret = ParseInterface() && ret; 69 continue; 70 case Token::SEQUENCEABLE: 71 ret = ParseSequenceable() && ret; 72 continue; 73 case Token::COMMENT_LINE: 74 lexer_.GetToken(); 75 continue; 76 default: 77 LogError(token, String::Format("%s is not expected.", lexer_.DumpToken().string())); 78 lexer_.GetToken(); 79 ret = false; 80 continue; 81 } 82 } 83 lexer_.GetToken(); 84 85 return ret; 86} 87 88bool Parser::ParseLicense() 89{ 90 Token token = lexer_.PeekToken(false); 91 if (token != Token::COMMENT_BLOCK) { 92 return false; 93 } 94 95 lexer_.GetToken(false); 96 97 module_->SetLicense(lexer_.GetComment()); 98 99 return true; 100} 101 102bool Parser::ParseInterface() 103{ 104 bool ret = true; 105 bool hasProperties = false; 106 bool oneway = false; 107 Token token = lexer_.GetToken(); 108 if (token == Token::BRACKETS_LEFT) { 109 token = lexer_.PeekToken(); 110 if (token != Token::ONEWAY) { 111 LogError(Token::IDENTIFIER, 112 String::Format("\"%s\" is an illegal interface property.", lexer_.DumpToken().string())); 113 if (token != Token::BRACKETS_RIGHT) { 114 lexer_.SkipCurrentLine(Lexer::TokenToChar(Token::BRACKETS_RIGHT)); 115 } 116 ret = false; 117 } 118 lexer_.GetToken(); 119 oneway = true; 120 hasProperties = true; 121 token = lexer_.PeekToken(); 122 if (token != Token::BRACKETS_RIGHT) { 123 LogError(Token::IDENTIFIER, String("\"]\" is expected.")); 124 while (token != Token::BRACKETS_RIGHT && token != Token::INTERFACE && token != Token::END_OF_FILE) { 125 lexer_.GetToken(); 126 token = lexer_.PeekToken(); 127 } 128 ret = false; 129 } else { 130 lexer_.GetToken(); 131 } 132 133 token = lexer_.PeekToken(); 134 if (token != Token::INTERFACE) { 135 LogError(Token::IDENTIFIER, String("\"interface\" is expected.")); 136 ret = false; 137 } else { 138 lexer_.GetToken(); 139 } 140 } 141 String interfaceFullName; 142 bool middleRes = ParseInterfaceMiddle(token, interfaceFullName); 143 if (!middleRes) { 144 return middleRes; 145 } 146 return ParseInterfaceEnd(token, interfaceFullName, hasProperties, oneway, ret); 147} 148 149bool Parser::ParseInterfaceMiddle(Token& token, String& interfaceFullName) 150{ 151 token = lexer_.PeekToken(); 152 if (token != Token::IDENTIFIER) { 153 LogError(token, String::Format("%s is not expected.", lexer_.DumpToken().string())); 154 lexer_.SkipCurrentLine(); 155 return false; 156 } else { 157 lexer_.GetToken(); 158 interfaceFullName = lexer_.GetIdentifier(); 159 token = lexer_.PeekToken(); 160 } 161 if (token != Token::SEMICOLON && token != Token::BRACES_LEFT) { 162 LogError(token, String::Format("%s is not expected.", lexer_.DumpToken().string())); 163 lexer_.SkipCurrentLine(); 164 return false; 165 } 166 167 if (interfaceFullName.IsEmpty()) { 168 LogError(Token::IDENTIFIER, String("Interface name is expected.")); 169 return false; 170 } else if (!IsValidTypeName(interfaceFullName)) { 171 LogError(Token::IDENTIFIER, String::Format("Interface name \"%s\" is illegal.", interfaceFullName.string())); 172 return false; 173 } else if (interfaceFullName.IndexOf(".") == -1) { 174 if (!(options_.GetTargetLanguage().Equals("ts")) && !(options_.GetTargetLanguage().Equals("rust"))) { 175 LogError(Token::IDENTIFIER, String::Format("Interface name \"%s\" does not have namespace.", 176 interfaceFullName.string())); 177 return false; 178 } 179 } 180 return true; 181} 182 183bool Parser::ParseInterfaceEnd(Token& token, String& interfaceFullName, bool hasProperties, bool oneway, bool ret) 184{ 185 AutoPtr<ASTInterfaceType> interface = new ASTInterfaceType(); 186 parsingInterface_ = interface; 187 int index = interfaceFullName.LastIndexOf('.'); 188 if (index != -1) { 189 interface->SetName(interfaceFullName.Substring(index + 1)); 190 interface->SetNamespace(module_->ParseNamespace(interfaceFullName.Substring(0, index + 1))); 191 } else { 192 interface->SetName(interfaceFullName); 193 interface->SetNamespace(NameSpaceEmpty()); 194 } 195 // read ';' 196 lexer_.GetToken(); 197 if (token == Token::SEMICOLON) { 198 if (hasProperties) { 199 LogError(Token::IDENTIFIER, String("Interface forward declaration should not have properties.")); 200 return false; 201 } 202 interface->SetExternal(true); 203 module_->AddInterface(interface); 204 return true; 205 } else { 206 if (!interface->GetName().Equals(module_->GetName())) { 207 LogError(Token::IDENTIFIER, String::Format("Module name \"%s\" is not equal to interface name \"%s\".", 208 module_->GetName().string(), interface->GetName().string())); 209 return false; 210 } 211 212 interface->SetLicense(module_->GetLicense()); 213 interface->SetOneway(oneway); 214 215 while (token != Token::BRACES_RIGHT && token != Token::END_OF_FILE) { 216 ret = ParseMethod(interface) && ret; 217 token = lexer_.PeekToken(); 218 } 219 220 if (token != Token::BRACES_RIGHT) { 221 ret = false; 222 } else { 223 lexer_.GetToken(); 224 module_->AddInterface(interface); 225 } 226 return ret; 227 } 228 return true; 229} 230 231bool Parser::ParseMethodProperties(bool& oneway, bool& cacheable, int& cacheTime) 232{ 233 Token token; 234 bool isParseOneway = false; 235 236 oneway = false; 237 cacheable = false; 238 lexer_.GetToken(); 239 token = lexer_.PeekToken(); 240 while (token != Token::BRACKETS_RIGHT && token != Token::END_OF_FILE) { 241 lexer_.GetToken(); 242 if (token != Token::ONEWAY && token != Token::CACHEABLE) { 243 LogError(Token::IDENTIFIER, String::Format("\"%s\" is an illegal method property.", 244 lexer_.DumpToken().string())); 245 break; 246 } 247 248 if (token == Token::ONEWAY && isParseOneway == false) { 249 oneway = true; 250 isParseOneway = true; 251 } else if (token == Token::CACHEABLE && cacheable == false) { 252 if (!lexer_.ParseCacheable(cacheTime)) { 253 LogError(Token::CACHEABLE, "cacheable time format is incorrect."); 254 return false; 255 } 256 cacheable = true; 257 } else { 258 return false; 259 } 260 261 token = lexer_.PeekToken(); 262 if (token == Token::COMMA) { 263 lexer_.GetToken(); 264 token = lexer_.PeekToken(); 265 } 266 } 267 268 if (token != Token::BRACKETS_RIGHT) { 269 LogError(Token::IDENTIFIER, String("\"]\" is expected.")); 270 return false; 271 } else { 272 lexer_.GetToken(); 273 } 274 return true; 275} 276 277void Parser::SetMethodAttr(ASTMethod* method, ASTType *returnType, bool oneway, bool cacheable, int cacheTime) 278{ 279 method->SetName(lexer_.GetIdentifier()); 280 method->SetOneway(oneway); 281 method->SetReturnType(returnType); 282 if (cacheable == true) { 283 method->SetCacheable(cacheTime); 284 module_->SetHasCacheableProxyMethods(true); 285 } 286 287 return; 288} 289 290bool Parser::ParseMethodName(Token& token, ASTType* type, ASTInterfaceType* interface) 291{ 292 if (type == nullptr) { 293 token = lexer_.PeekToken(); 294 if (token == Token::BRACES_RIGHT) { 295 return false; 296 } 297 // jump over colon 298 lexer_.GetToken(); 299 while (token != Token::SEMICOLON && token != Token::END_OF_FILE) { 300 token = lexer_.PeekToken(); 301 if (token == Token::BRACES_RIGHT) { 302 break; 303 } 304 lexer_.GetToken(); 305 } 306 return false; 307 } 308 if (interface->IsOneway()) { 309 if (!type->IsVoidType()) { 310 LogError(token, String("void return type expected in oneway interface.")); 311 return false; 312 } 313 } 314 token = lexer_.PeekToken(); 315 if (token != Token::IDENTIFIER) { 316 LogError(token, String("Method name is expected.")); 317 if (token == Token::BRACES_RIGHT) { 318 return false; 319 } 320 // jump over colon 321 lexer_.GetToken(); 322 while (token != Token::SEMICOLON && token != Token::END_OF_FILE) { 323 token = lexer_.PeekToken(); 324 if (token == Token::BRACES_RIGHT) { 325 break; 326 } 327 lexer_.GetToken(); 328 } 329 return false; 330 } 331 return true; 332} 333 334bool Parser::ParseMethodBrackets(Token& token, ASTMethod* method, bool& ret) 335{ 336 if (method->IsOneway()) { 337 if (!method->GetReturnType()->IsVoidType()) { 338 LogError(token, String("void return type expected in oneway method.")); 339 return false; 340 } 341 } 342 token = lexer_.PeekToken(); 343 if (token != Token::PARENTHESES_LEFT) { 344 LogError(token, String("\"(\" is expected.")); 345 if (token == Token::BRACES_RIGHT) { 346 return false; 347 } 348 // jump over colon 349 lexer_.GetToken(); 350 while (token != Token::SEMICOLON && token != Token::END_OF_FILE) { 351 token = lexer_.PeekToken(); 352 if (token == Token::BRACES_RIGHT) { 353 break; 354 } 355 lexer_.GetToken(); 356 } 357 return false; 358 } 359 token = lexer_.GetToken(); 360 361 token = lexer_.PeekToken(); 362 while (token != Token::PARENTHESES_RIGHT && token != Token::END_OF_FILE) { 363 ret = ParseParameter(method) && ret; 364 token = lexer_.PeekToken(); 365 if (token == Token::COMMA) { 366 lexer_.GetToken(); 367 token = lexer_.PeekToken(); 368 } 369 } 370 return true; 371} 372 373bool Parser::ParseMethod(ASTInterfaceType* interface) 374{ 375 bool ret = true; 376 bool oneway = false; 377 bool cacheable = false; 378 int cacheTime; 379 Token token = lexer_.PeekToken(); 380 if ((token == Token::BRACKETS_LEFT) && (ParseMethodProperties(oneway, cacheable, cacheTime) == false)) { 381 return false; 382 } 383 384 AutoPtr<ASTType> type = ParseType(); 385 if (!ParseMethodName(token, type, interface)) { 386 return false; 387 } 388 389 token = lexer_.GetToken(); 390 AutoPtr<ASTMethod> method = new ASTMethod(); 391 if (method == nullptr) { 392 LogError(token, String("method is nullptr.")); 393 return false; 394 } 395 SetMethodAttr(method, type, oneway, cacheable, cacheTime); 396 if (!ParseMethodBrackets(token, method, ret)) { 397 return false; 398 } 399 400 if (interface->IsOneway() || method->IsOneway()) { 401 for (size_t i = 0; i< method->GetParameterNumber(); i++) { 402 auto parameter = method->GetParameter(i); 403 if (parameter->IsOutParameter()) { 404 LogError(token, String("out parameter type not expected in oneway method.")); 405 return false; 406 } 407 } 408 } 409 lexer_.GetToken(); 410 if (!ret) { 411 lexer_.SkipCurrentLine(); 412 return false; 413 } 414 415 token = lexer_.PeekToken(); 416 if (token != Token::SEMICOLON) { 417 LogError(token, String("\";\" is expected.")); 418 if (token != Token::BRACES_RIGHT) { 419 lexer_.SkipCurrentLine(Lexer::TokenToChar(Token::BRACES_RIGHT)); 420 } 421 return false; 422 } 423 lexer_.GetToken(); 424 425 interface->AddMethod(method); 426 427 return ret; 428} 429 430bool Parser::ParseParameterPeek(Token& token) 431{ 432 if (token != Token::BRACKETS_LEFT) { 433 LogError(token, String("\"[\" is expected.")); 434 // jump to ',' or ')' 435 while (token != Token::COMMA && token != Token::PARENTHESES_RIGHT && token != Token::END_OF_FILE) { 436 lexer_.GetToken(); 437 token = lexer_.PeekToken(); 438 } 439 return false; 440 } 441 return true; 442} 443 444bool Parser::ParseParameterInOut(Token& token, ASTParameter* parameter) 445{ 446 token = lexer_.PeekToken(); 447 while (token != Token::BRACKETS_RIGHT && token != Token::END_OF_FILE) { 448 switch (token) { 449 case Token::IN: 450 lexer_.GetToken(); 451 parameter->SetInParameter(true); 452 break; 453 case Token::OUT: 454 lexer_.GetToken(); 455 parameter->SetOutParameter(true); 456 break; 457 case Token::INOUT: 458 lexer_.GetToken(); 459 parameter->SetInParameter(true); 460 parameter->SetOutParameter(true); 461 break; 462 default: 463 LogError(token, String("\"in\" or \"out\" or \"inout\" is expected.")); 464 break; 465 } 466 token = lexer_.PeekToken(); 467 if (token == Token::COMMA) { 468 lexer_.GetToken(); 469 token = lexer_.PeekToken(); 470 continue; 471 } 472 if (token != Token::BRACKETS_RIGHT) { 473 LogError(token, String("\",\" or \"]\" is expected.")); 474 // jump to ',' or ')' 475 while (token != Token::COMMA && token != Token::PARENTHESES_RIGHT && token != Token::END_OF_FILE) { 476 lexer_.GetToken(); 477 token = lexer_.PeekToken(); 478 } 479 return false; 480 } 481 } 482 return true; 483} 484 485bool Parser::ParseParameter(ASTMethod* method) 486{ 487 Token token = lexer_.PeekToken(); 488 if (!ParseParameterPeek(token)) { 489 return false; 490 } 491 lexer_.GetToken(); 492 493 AutoPtr<ASTParameter> parameter = new ASTParameter(); 494 if (parameter == nullptr) { 495 return false; 496 } 497 498 if (!ParseParameterInOut(token, parameter)) { 499 return false; 500 } 501 502 // read ']' 503 lexer_.GetToken(); 504 505 AutoPtr<ASTType> type = ParseType(); 506 if (type == nullptr) { 507 // jump to ',' or ')' 508 while (token != Token::COMMA && token != Token::PARENTHESES_RIGHT && token != Token::END_OF_FILE) { 509 lexer_.GetToken(); 510 token = lexer_.PeekToken(); 511 } 512 return false; 513 } 514 515 token = lexer_.PeekToken(); 516 if (token != Token::IDENTIFIER) { 517 LogError(token, String("Parameter name is expected.")); 518 // jump to ',' or ')' 519 while (token != Token::COMMA && token != Token::PARENTHESES_RIGHT && token != Token::END_OF_FILE) { 520 lexer_.GetToken(); 521 token = lexer_.PeekToken(); 522 } 523 return false; 524 } 525 lexer_.GetToken(); 526 527 parameter->SetName(lexer_.GetIdentifier()); 528 parameter->SetType(type); 529 method->AddParameter(parameter); 530 531 return true; 532} 533 534AutoPtr<ASTType> Parser::ParseType() 535{ 536 AutoPtr<ASTType> type; 537 538 Token token = lexer_.PeekToken(); 539 if (IsPrimitiveType(token)) { 540 lexer_.GetToken(); 541 type = module_->FindType(lexer_.DumpToken()); 542 } else if (token == Token::LIST) { 543 type = ParseList(); 544 } else if (token == Token::MAP) { 545 type = ParseMap(); 546 } else if (token == Token::IDENTIFIER) { 547 lexer_.GetToken(); 548 if (parsingInterface_ != nullptr && 549 parsingInterface_->GetName().Equals(lexer_.GetIdentifier())) { 550 type = parsingInterface_.Get(); 551 } else { 552 type = module_->FindType(lexer_.GetIdentifier()); 553 } 554 } else { 555 LogError(token, String("Type name is expected.")); 556 return nullptr; 557 } 558 559 if (type == nullptr || type.Get() == nullptr) { 560 LogError(token, String::Format("Type \"%s\" was not declared in the module.", lexer_.DumpToken().string())); 561 return nullptr; 562 } 563 564 token = lexer_.PeekToken(); 565 if (token == Token::BRACKETS_LEFT) { 566 lexer_.GetToken(); 567 token = lexer_.PeekToken(); 568 if (token != Token::BRACKETS_RIGHT) { 569 LogError(token, String("\"]\" is expected.")); 570 return nullptr; 571 } 572 lexer_.GetToken(); 573 574 AutoPtr<ASTArrayType> arrayType = new ASTArrayType(); 575 if (arrayType == nullptr) { 576 LogError(token, String("arrayType is nullptr.")); 577 return nullptr; 578 } 579 arrayType->SetElementType(type); 580 581 type = module_->FindType(arrayType->ToString()); 582 if (type == nullptr) { 583 module_->AddType(arrayType); 584 type = static_cast<ASTType*>(arrayType.Get()); 585 } 586 } 587 588 return type; 589} 590 591AutoPtr<ASTType> Parser::ParseList() 592{ 593 lexer_.GetToken(); 594 595 Token token = lexer_.PeekToken(); 596 if (token != Token::ANGLE_BRACKETS_LEFT) { 597 LogError(token, String("\"<\" is expected.")); 598 return nullptr; 599 } 600 lexer_.GetToken(); 601 602 AutoPtr<ASTType> type = ParseType(); 603 if (type == nullptr) { 604 lexer_.SkipCurrentLine('>'); 605 return nullptr; 606 } 607 608 token = lexer_.PeekToken(); 609 if (token != Token::ANGLE_BRACKETS_RIGHT) { 610 LogError(token, String("\">\" is expected.")); 611 return nullptr; 612 } 613 lexer_.GetToken(); 614 615 AutoPtr<ASTListType> list = new ASTListType(); 616 list->SetElementType(type); 617 618 AutoPtr<ASTType> ret = module_->FindType(list->ToString()); 619 if (ret == nullptr) { 620 module_->AddType(list); 621 ret = list.Get(); 622 } 623 624 return ret; 625} 626 627AutoPtr<ASTType> Parser::ParseMap() 628{ 629 lexer_.GetToken(); 630 631 Token token = lexer_.PeekToken(); 632 if (token != Token::ANGLE_BRACKETS_LEFT) { 633 LogError(token, String("\"<\" is expected.")); 634 return nullptr; 635 } 636 lexer_.GetToken(); 637 638 AutoPtr<ASTType> keyType = ParseType(); 639 if (keyType == nullptr) { 640 lexer_.SkipCurrentLine('>'); 641 return nullptr; 642 } 643 644 token = lexer_.PeekToken(); 645 if (token != Token::COMMA) { 646 LogError(token, String("\",\" is expected.")); 647 return nullptr; 648 } 649 lexer_.GetToken(); 650 651 AutoPtr<ASTType> valueType = ParseType(); 652 if (valueType == nullptr) { 653 lexer_.SkipCurrentLine('>'); 654 return nullptr; 655 } 656 657 token = lexer_.PeekToken(); 658 if (token != Token::ANGLE_BRACKETS_RIGHT) { 659 LogError(token, String("\">\" is expected.")); 660 return nullptr; 661 } 662 lexer_.GetToken(); 663 664 AutoPtr<ASTMapType> map = new ASTMapType(); 665 map->SetKeyType(keyType); 666 map->SetValueType(valueType); 667 668 AutoPtr<ASTType> ret = module_->FindType(map->ToString()); 669 if (ret == nullptr) { 670 module_->AddType(map); 671 ret = map.Get(); 672 } 673 674 return ret; 675} 676 677bool Parser::ParseSequenceable() 678{ 679 lexer_.GetToken(); 680 681 String classFullName; 682 683 Token token = lexer_.PeekToken(); 684 if (token != Token::IDENTIFIER) { 685 LogError(token, String::Format("%s is not expected.", lexer_.DumpToken().string())); 686 lexer_.SkipCurrentLine(); 687 return false; 688 } else { 689 lexer_.GetToken(); 690 classFullName = lexer_.GetIdentifier(); 691 token = lexer_.PeekToken(); 692 } 693 694 if (token != Token::SEMICOLON) { 695 LogError(token, String::Format("%s is not expected.", lexer_.DumpToken().string())); 696 lexer_.SkipCurrentLine(); 697 return false; 698 } 699 700 // read ';' 701 lexer_.GetToken(); 702 703 if (classFullName.IsEmpty()) { 704 LogError(Token::IDENTIFIER, String("Class name is expected.")); 705 return false; 706 } else if (!IsValidTypeName(classFullName)) { 707 LogError(Token::IDENTIFIER, String::Format("Class name \"%s\" is illegal.", classFullName.string())); 708 return false; 709 } 710 711 AutoPtr<ASTSequenceableType> sequenceable = new ASTSequenceableType(); 712 int index = classFullName.LastIndexOf('.'); 713 if (index != -1) { 714 sequenceable->SetName(classFullName.Substring(index + 1)); 715 sequenceable->SetNamespace(module_->ParseNamespace(classFullName.Substring(0, index + 1))); 716 } else { 717 sequenceable->SetName(classFullName); 718 sequenceable->SetNamespace(NameSpaceEmpty()); 719 } 720 module_->AddSequenceable(sequenceable); 721 722 return true; 723} 724 725bool Parser::CheckIntegrity() 726{ 727 bool definedInterface = false; 728 size_t interfaceNumber = module_->GetInterfaceNumber(); 729 for (size_t i = 0; i < interfaceNumber; i++) { 730 if (!module_->GetInterface(i)->IsExternal()) { 731 definedInterface = true; 732 break; 733 } 734 } 735 if (!definedInterface) { 736 LogError(Token::UNKNOWN, String("An interface is not defined.")); 737 return false; 738 } 739 740 return true; 741} 742 743bool Parser::IsValidTypeName(const String& typeName) 744{ 745 if (typeName[0] == '.') { 746 return false; 747 } 748 749 if (typeName[typeName.GetLength() - 1] == '.') { 750 return false; 751 } 752 753 return true; 754} 755 756void Parser::LogError(Token token, const String& message) 757{ 758 AutoPtr<ErrorInfo> error = new ErrorInfo(); 759 760 String sourceFile = lexer_.GetSourceFile()->GetPath(); 761#ifdef __MINGW32__ 762 error->file_ = sourceFile.Substring(sourceFile.LastIndexOf('\\') + 1); 763#else 764 error->file_ = sourceFile.Substring(sourceFile.LastIndexOf('/') + 1); 765#endif 766 error->lineNo_ = lexer_.GetTokenLineNumber(); 767 error->columnNo_ = lexer_.GetTokenColumnNumber(); 768 error->message_ = message; 769 770 if (errors_ == nullptr) { 771 errors_ = error; 772 } else { 773 ErrorInfo* pos = errors_; 774 while (pos->next_ != nullptr) { 775 pos = pos->next_; 776 } 777 pos->next_ = error; 778 } 779} 780 781void Parser::ShowError() 782{ 783 ErrorInfo* error = errors_; 784 while (error != nullptr) { 785 Logger::E(tag, "%s[line %d, column %d] %s", error->file_.string(), 786 error->lineNo_, error->columnNo_, error->message_.string()); 787 error = error->next_; 788 } 789} 790 791AutoPtr<ASTNamespace> Parser::NameSpaceEmpty() 792{ 793 AutoPtr<ASTNamespace> currNspace = nullptr; 794 currNspace = module_->FindNamespace(""); 795 if (currNspace == nullptr) { 796 currNspace = new ASTNamespace(""); 797 module_->AddNamespace(currNspace); 798 } 799 return currNspace; 800} 801} // namespace Idl 802} // namespace OHOS 803