1 /* 2 * Copyright (c) 2024 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 18 #include <regex> 19 20 #include "ast/ast_array_type.h" 21 #include "ast/ast_enum_type.h" 22 #include "ast/ast_map_type.h" 23 #include "ast/ast_parameter.h" 24 #include "ast/ast_sequenceable_type.h" 25 #include "ast/ast_smq_type.h" 26 #include "ast/ast_struct_type.h" 27 #include "ast/ast_union_type.h" 28 #include "util/logger.h" 29 #include "util/string_builder.h" 30 31 namespace OHOS { 32 namespace Idl { 33 static constexpr const char *RE_BIN_DIGIT = "0[b][0|1]+"; // binary digit 34 static constexpr const char *RE_OCT_DIGIT = "0[0-7]+"; // octal digit 35 static constexpr const char *RE_DEC_DIGIT = "[0-9]+"; // decimal digit 36 static constexpr const char *RE_HEX_DIFIT = "0[xX][0-9a-fA-F]+"; // hexadecimal digit 37 static constexpr const char *RE_DIGIT_SUFFIX = "(u|l|ll|ul|ull|)$"; 38 static constexpr const char *RE_IDENTIFIER = "[a-zA-Z_][a-zA-Z0-9_]*"; 39 40 static constexpr unsigned int RE_PACKAGE_NUM = 3; 41 static constexpr unsigned int RE_PACKAGE_INDEX = 0; 42 static constexpr unsigned int RE_PACKAGE_MAJOR_VER_INDEX = 1; 43 static constexpr unsigned int RE_PACKAGE_MINOR_VER_INDEX = 2; 44 45 static const std::regex RE_PACKAGE(std::string(RE_IDENTIFIER) + "(?:\\." + std::string(RE_IDENTIFIER) + ")*\\.[V|v]" + 46 "(" + std::string(RE_DEC_DIGIT) + ")_(" + std::string(RE_DEC_DIGIT) + ")"); 47 static const std::regex RE_PACKAGE_OR_IMPORT_SM(std::string(RE_IDENTIFIER) + 48 "(?:\\." + std::string(RE_IDENTIFIER) + ")*"); 49 static const std::regex RE_IMPORT(std::string(RE_IDENTIFIER) + "(?:\\." + std::string(RE_IDENTIFIER) + ")*\\.[V|v]" + 50 std::string(RE_DEC_DIGIT) + "_" + std::string(RE_DEC_DIGIT) + "." + std::string(RE_IDENTIFIER)); 51 static const std::regex RE_BIN_NUM(std::string(RE_BIN_DIGIT) + std::string(RE_DIGIT_SUFFIX), 52 std::regex_constants::icase); 53 static const std::regex RE_OCT_NUM(std::string(RE_OCT_DIGIT) + std::string(RE_DIGIT_SUFFIX), 54 std::regex_constants::icase); 55 static const std::regex RE_DEC_NUM(std::string(RE_DEC_DIGIT) + std::string(RE_DIGIT_SUFFIX), 56 std::regex_constants::icase); 57 static const std::regex RE_HEX_NUM(std::string(RE_HEX_DIFIT) + std::string(RE_DIGIT_SUFFIX), 58 std::regex_constants::icase); 59 AutoPtr<ASTEnumType> g_currentEnum = nullptr; 60 Parse(const std::vector<FileDetail> & fileDetails)61 bool Parser::Parse(const std::vector<FileDetail> &fileDetails) 62 { 63 for (const auto &fileDetail : fileDetails) { 64 if (!ParseOne(fileDetail.filePath_)) { 65 return false; 66 } 67 } 68 69 return PostProcess(); 70 } 71 ParseOne(const std::string & sourceFile)72 bool Parser::ParseOne(const std::string &sourceFile) 73 { 74 if (!Reset(sourceFile)) { 75 return false; 76 } 77 78 bool ret = ParseFile(); 79 IntfTypeChecker checker(ast_); 80 ret = checker.CheckIntegrity() && ret; 81 ret = AddAst(ast_) && ret; 82 if (!ret || !errors_.empty()) { 83 ShowError(); 84 return false; 85 } 86 87 return true; 88 } 89 Reset(const std::string & sourceFile)90 bool Parser::Reset(const std::string &sourceFile) 91 { 92 if (!lexer_.Reset(sourceFile)) { 93 Logger::E(TAG, "Fail to open file '%s'.", sourceFile.c_str()); 94 return false; 95 } 96 97 errors_.clear(); 98 ast_ = nullptr; 99 return true; 100 } 101 ParseFile()102 bool Parser::ParseFile() 103 { 104 ast_ = new AST(); 105 ast_->SetIdlFile(lexer_.GetFilePath()); 106 ast_->SetLicense(ParseLicense()); 107 108 TokenType tokenKind; 109 bool ret = true; 110 while (((tokenKind = lexer_.PeekToken().kind) != TokenType::END_OF_FILE) && ret) { 111 switch (tokenKind) { 112 case TokenType::PACKAGE: 113 ret = ParsePackage() && ret; 114 continue; 115 case TokenType::INTERFACE_TOKEN: 116 ret = ParseInterfaceToken() && ret; 117 continue; 118 case TokenType::SUPPORT_DELEGATOR: 119 ret = ParseSupportDelegator() && ret; 120 continue; 121 case TokenType::IMPORT: 122 case TokenType::SEQ: 123 ret = ParseImports() && ret; 124 continue; 125 default: 126 ret = ParseTypeDecls() && ret; 127 continue; 128 } 129 } 130 131 SetAstFileType(); 132 return ret; 133 } 134 ParseLicense()135 std::string Parser::ParseLicense() 136 { 137 Token token = lexer_.PeekToken(false); 138 if (token.kind == TokenType::COMMENT_BLOCK) { 139 lexer_.GetToken(false); 140 return token.value; 141 } 142 143 return std::string(""); 144 } 145 ParsePackage()146 bool Parser::ParsePackage() 147 { 148 // package 149 Token token = lexer_.PeekToken(); 150 if (token.kind != TokenType::PACKAGE) { 151 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected 'package'")); 152 return false; 153 } 154 lexer_.GetToken(); 155 156 // package name 157 token = lexer_.PeekToken(); 158 if (token.kind != TokenType::ID) { 159 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected name of package")); 160 lexer_.SkipToken(TokenType::SEMICOLON); 161 return false; 162 } 163 std::string packageName = token.value; 164 lexer_.GetToken(); 165 166 // expect symbol ";" 167 token = lexer_.PeekToken(); 168 if (token.kind != TokenType::SEMICOLON) { 169 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ';'")); 170 return false; 171 } 172 lexer_.GetToken(); 173 174 if (packageName.empty()) { 175 LogError(__func__, __LINE__, std::string("package name is not expected.")); 176 return false; 177 } else if (!CheckPackageName(lexer_.GetFilePath(), packageName)) { 178 LogError(__func__, __LINE__, StringHelper::Format( 179 "package name '%s' does not match file apth '%s'.", packageName.c_str(), lexer_.GetFilePath().c_str())); 180 return false; 181 } 182 183 if (!ParserPackageInfo(packageName)) { 184 LogError(__func__, __LINE__, StringHelper::Format("parse package '%s' infomation failed.", 185 packageName.c_str())); 186 return false; 187 } 188 189 return true; 190 } 191 ParserPackageInfo(const std::string & packageName)192 bool Parser::ParserPackageInfo(const std::string &packageName) 193 { 194 std::cmatch result; 195 if (Options::GetInstance().GetInterfaceType() == InterfaceType::HDI) { 196 if (!std::regex_match(packageName.c_str(), result, RE_PACKAGE) || (result.size() < RE_PACKAGE_NUM)) { 197 return false; 198 } 199 200 ast_->SetPackageName(result.str(RE_PACKAGE_INDEX).c_str()); 201 size_t majorVersion = std::stoul(result.str(RE_PACKAGE_MAJOR_VER_INDEX)); 202 size_t minorVersion = std::stoul(result.str(RE_PACKAGE_MINOR_VER_INDEX)); 203 ast_->SetVersion(majorVersion, minorVersion); 204 } else { 205 if (!std::regex_match(packageName.c_str(), result, RE_PACKAGE_OR_IMPORT_SM)) { 206 return false; 207 } 208 ast_->SetPackageName(result.str(RE_PACKAGE_INDEX).c_str()); 209 } 210 return true; 211 } 212 ParseInterfaceToken()213 bool Parser::ParseInterfaceToken() 214 { 215 Token token = lexer_.PeekToken(); 216 if (token.kind != TokenType::INTERFACE_TOKEN) { 217 LogError(__func__, __LINE__, token, StringHelper::Format("expected 'interface token'")); 218 return false; 219 } 220 lexer_.GetToken(); 221 222 token = lexer_.PeekToken(); 223 if (token.kind != TokenType::ID) { 224 LogError(__func__, __LINE__, token, StringHelper::Format("expected name of interface_token before '%s' token", 225 token.value.c_str())); 226 lexer_.SkipToken(TokenType::SEMICOLON); 227 return false; 228 } 229 std::string interfaceToken = token.value; 230 lexer_.GetToken(); 231 232 token = lexer_.PeekToken(); 233 if (token.kind != TokenType::SEMICOLON) { 234 LogError(__func__, __LINE__, token, StringHelper::Format("expected ';' before '%s' token", 235 token.value.c_str())); 236 return false; 237 } 238 lexer_.GetToken(); 239 240 if (interfaceToken.empty()) { 241 LogError(__func__, __LINE__, token, StringHelper::Format("interface_token name is not expected.")); 242 return false; 243 } 244 245 ast_->SetInterfaceToken(interfaceToken); 246 return true; 247 } 248 ParseSupportDelegator()249 bool Parser::ParseSupportDelegator() 250 { 251 Token token = lexer_.PeekToken(); 252 if (token.kind != TokenType::SUPPORT_DELEGATOR) { 253 LogError(__func__, __LINE__, token, StringHelper::Format("expected 'support_delegator'")); 254 return false; 255 } 256 lexer_.GetToken(); 257 258 token = lexer_.PeekToken(); 259 if (token.kind != TokenType::ID) { 260 LogError(__func__, __LINE__, token, StringHelper::Format("expected name of suport_delegator before '%s' token", 261 token.value.c_str())); 262 lexer_.SkipToken(TokenType::SEMICOLON); 263 return false; 264 } 265 std::string supportDelegator = token.value; 266 lexer_.GetToken(); 267 268 token = lexer_.PeekToken(); 269 if (token.kind != TokenType::SEMICOLON) { 270 LogError(__func__, __LINE__, token, StringHelper::Format("expected ';' before '%s' token", 271 token.value.c_str())); 272 return false; 273 } 274 lexer_.GetToken(); 275 276 if (supportDelegator.empty()) { 277 LogError(__func__, __LINE__, token, StringHelper::Format("support_delegator name is not expected.")); 278 return false; 279 } 280 281 ast_->SetSupportDelegator(supportDelegator); 282 return true; 283 } 284 ParseImports()285 bool Parser::ParseImports() 286 { 287 Token token = lexer_.PeekToken(); 288 TokenType kind = token.kind; 289 lexer_.GetToken(); 290 291 // name 292 token = lexer_.PeekToken(); 293 if (token.kind != TokenType::ID) { 294 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected identifier")); 295 lexer_.SkipToken(TokenType::SEMICOLON); 296 token = lexer_.PeekToken(); 297 return false; 298 } 299 300 if (kind == TokenType::IMPORT) { 301 ParseImportInfo(); 302 } else { 303 ParseSequenceableInfo(); 304 } 305 lexer_.GetToken(); 306 307 // expect symbol ";" 308 token = lexer_.PeekToken(); 309 if (token.kind != TokenType::SEMICOLON) { 310 LogError(__func__, __LINE__, token, StringHelper::Format("expected ';' before '%s'.", token.value.c_str())); 311 return false; 312 } 313 lexer_.GetToken(); 314 315 return true; 316 } 317 ParseImportInfo()318 void Parser::ParseImportInfo() 319 { 320 Token token = lexer_.PeekToken(); 321 std::string importName = token.value; 322 if (importName.empty()) { 323 LogError(__func__, __LINE__, token, std::string("import name is empty")); 324 return; 325 } 326 327 if (!CheckImport(importName)) { 328 LogError(__func__, __LINE__, token, std::string("import name is illegal")); 329 return; 330 } 331 332 auto iter = allAsts_.find(importName); 333 AutoPtr<AST> importAst = (iter != allAsts_.end()) ? iter->second : nullptr; 334 if (importAst == nullptr) { 335 LogError(__func__, __LINE__, token, 336 StringHelper::Format("can not find idl file from import name '%s'", importName.c_str())); 337 return; 338 } 339 340 if (!CheckImportsVersion(importAst)) { 341 LogError(__func__, __LINE__, token, 342 std::string("extends import version must less than current import version")); 343 return; 344 } 345 346 if (!ast_->AddImport(importAst)) { 347 LogError(__func__, __LINE__, token, StringHelper::Format("multiple import of '%s'", importName.c_str())); 348 } 349 } 350 ParseSequenceableInfo()351 void Parser::ParseSequenceableInfo() 352 { 353 Token token = lexer_.PeekToken(); 354 std::string seqName = token.value; 355 if (seqName.empty()) { 356 LogError(__func__, __LINE__, token, std::string("sequenceable name is empty")); 357 return; 358 } 359 360 AutoPtr<ASTSequenceableType> seqType = new ASTSequenceableType(); 361 size_t index = seqName.rfind('.'); 362 if (index != std::string::npos) { 363 seqType->SetName(seqName.substr(index + 1)); 364 seqType->SetNamespace(ast_->ParseNamespace(seqName)); 365 } else { 366 seqType->SetName(seqName); 367 seqType->SetNamespace(ast_->ParseNamespace("")); 368 } 369 370 AutoPtr<AST> seqAst = new AST(); 371 seqAst->SetFullName(seqName); 372 seqAst->AddSequenceableDef(seqType); 373 seqAst->SetAStFileType(ASTFileType::AST_SEQUENCEABLE); 374 ast_->AddImport(seqAst); 375 ast_->AddSequenceableDef(seqType); 376 AddAst(seqAst); 377 } 378 ParseTypeDecls()379 bool Parser::ParseTypeDecls() 380 { 381 Token token = lexer_.PeekToken(); 382 switch (token.kind) { 383 case TokenType::BRACKETS_LEFT: 384 ParseAttribute(); 385 break; 386 case TokenType::INTERFACE: 387 ParseInterface(); 388 break; 389 case TokenType::ENUM: 390 ParseEnumDeclaration(); 391 break; 392 case TokenType::STRUCT: 393 ParseStructDeclaration(); 394 break; 395 case TokenType::UNION: 396 ParseUnionDeclaration(); 397 break; 398 default: 399 LogError(__func__, __LINE__, token, StringHelper::Format("'%s' is not expected", token.value.c_str())); 400 lexer_.SkipToken(TokenType::SEMICOLON); 401 return false; 402 } 403 404 return true; 405 } 406 ParseAttribute()407 void Parser::ParseAttribute() 408 { 409 AttrSet attrs = ParseAttributeInfo(); 410 Token token = lexer_.PeekToken(); 411 switch (token.kind) { 412 case TokenType::INTERFACE: 413 ParseInterface(attrs); 414 break; 415 case TokenType::ENUM: 416 ParseEnumDeclaration(attrs); 417 break; 418 case TokenType::STRUCT: 419 ParseStructDeclaration(attrs); 420 break; 421 case TokenType::UNION: 422 ParseUnionDeclaration(attrs); 423 break; 424 default: 425 LogError(__func__, __LINE__, token, StringHelper::Format("'%s' is not expected", token.value.c_str())); 426 lexer_.SkipToken(token.kind); 427 break; 428 } 429 } 430 ParseAttributeInfo()431 AttrSet Parser::ParseAttributeInfo() 432 { 433 AttrSet attrs; 434 // [ 435 Token token = lexer_.PeekToken(); 436 if (token.kind != TokenType::BRACKETS_LEFT) { 437 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '['")); 438 lexer_.SkipToken(token.kind); 439 return attrs; 440 } 441 lexer_.GetToken(); 442 443 // attrunit 444 token = lexer_.PeekToken(); 445 while (token.kind != TokenType::BRACKETS_RIGHT && token.kind != TokenType::END_OF_FILE) { 446 if (!ParseAttrUnit(attrs)) { 447 return attrs; 448 } 449 // expect symbol "," 450 token = lexer_.PeekToken(); 451 if (token.kind == TokenType::COMMA) { 452 lexer_.GetToken(); 453 token = lexer_.PeekToken(); 454 continue; 455 } 456 // ] 457 if (token.kind == TokenType::BRACKETS_RIGHT) { 458 lexer_.GetToken(); 459 } else { 460 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ',' or ']'")); 461 lexer_.SkipToken(TokenType::BRACKETS_RIGHT); 462 } 463 break; 464 } 465 466 return attrs; 467 } 468 ParseAttrUnit(AttrSet & attrs)469 bool Parser::ParseAttrUnit(AttrSet &attrs) 470 { 471 Token token = lexer_.PeekToken(); 472 switch (token.kind) { 473 case TokenType::FULL: 474 case TokenType::LITE: 475 case TokenType::MINI: 476 case TokenType::CALLBACK: 477 case TokenType::ONEWAY: { 478 if (attrs.find(token) != attrs.end()) { 479 LogError(__func__, __LINE__, token, StringHelper::Format("Duplicate declared attributes '%s'", 480 token.value.c_str())); 481 } else { 482 attrs.insert(token); 483 } 484 lexer_.GetToken(); 485 return true; 486 } 487 case TokenType::CACHEABLE: { 488 if (attrs.find(token) != attrs.end()) { 489 LogError(__func__, __LINE__, token, StringHelper::Format("Duplicate declared attributes cacheable")); 490 } else { 491 if (!lexer_.ReadCacheableTime(token)) { 492 LogError(__func__, __LINE__, token, StringHelper::Format("Cacheable time parse failed")); 493 } 494 attrs.insert(token); 495 } 496 lexer_.GetToken(); 497 return true; 498 } 499 case TokenType::FREEZECONTROL: { 500 ParseAttrUnitFreezecontrol(attrs, token); 501 return true; 502 } 503 default: 504 LogError(__func__, __LINE__, token, StringHelper::Format("'%s' is a illegal attribute", 505 token.value.c_str())); 506 lexer_.SkipToken(TokenType::BRACKETS_RIGHT); 507 return false; 508 } 509 } 510 ParseAttrUnitFreezecontrol(AttrSet & attrs,Token & token)511 void Parser::ParseAttrUnitFreezecontrol(AttrSet &attrs, Token &token) 512 { 513 if (attrs.find(token) != attrs.end()) { 514 LogError(__func__, __LINE__, token, StringHelper::Format("Duplicate declared attr freezecontrol")); 515 } else { 516 attrs.insert(token); 517 lexer_.GetToken(); 518 token = lexer_.PeekToken(); 519 if (token.value == "]") { 520 LogError(__func__, __LINE__, token, StringHelper::Format("freezecontrol attr cannot be empty")); 521 } else if (token.kind == TokenType::ID) { 522 freezecontrolAttr_ = token.value; 523 } 524 } 525 lexer_.GetToken(); 526 } 527 ParseInterface(const AttrSet & attrs)528 void Parser::ParseInterface(const AttrSet &attrs) 529 { 530 AutoPtr<ASTInterfaceType> interfaceType = new ASTInterfaceType; 531 AutoPtr<ASTAttr> astAttr = ParseInfAttrInfo(attrs); 532 interfaceType->SetAttribute(astAttr); 533 534 lexer_.GetToken(); 535 Token token = lexer_.PeekToken(); 536 if (token.kind != TokenType::ID) { 537 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected interface name")); 538 } else { 539 size_t index = token.value.rfind('.'); 540 if (index != std::string::npos) { 541 interfaceType->SetName(StringHelper::SubStr(token.value, index + 1)); 542 interfaceType->SetNamespace(ast_->ParseNamespace(token.value)); 543 } else { 544 interfaceType->SetName(token.value); 545 interfaceType->SetNamespace(ast_->ParseNamespace(ast_->GetFullName())); 546 } 547 interfaceType->SetLicense(ast_->GetLicense()); 548 lexer_.GetToken(); 549 } 550 551 CheckInterfaceAttr(interfaceType, token); 552 ParseInterfaceExtends(interfaceType); 553 token = lexer_.PeekToken(); 554 if (token.kind == TokenType::SEMICOLON) { 555 ParseInterfaceExternal(interfaceType); 556 } else { 557 if (interfaceType->GetName() != ast_->GetName()) { 558 LogError(__func__, __LINE__, token, StringHelper::Format( 559 "interface name '%s' is not equal idl file name", interfaceType->GetName().c_str())); 560 } 561 ParseInterfaceBody(interfaceType); 562 } 563 interfaceType->SetVersion(ast_->GetMajorVer(), ast_->GetMinorVer()); 564 ast_->AddInterfaceDef(interfaceType); 565 } 566 ParseInfAttrInfo(const AttrSet & attrs)567 AutoPtr<ASTAttr> Parser::ParseInfAttrInfo(const AttrSet &attrs) 568 { 569 AutoPtr<ASTAttr> infAttr = new ASTAttr(); 570 InterfaceType interfaceType = Options::GetInstance().GetInterfaceType(); 571 for (const auto &attr : attrs) { 572 switch (attr.kind) { 573 case TokenType::FULL: 574 infAttr->SetValue(ASTAttr::FULL); 575 break; 576 case TokenType::LITE: 577 infAttr->SetValue(ASTAttr::LITE); 578 break; 579 case TokenType::MINI: 580 infAttr->SetValue(ASTAttr::MINI); 581 break; 582 case TokenType::CALLBACK: 583 infAttr->SetValue(ASTAttr::CALLBACK); 584 break; 585 case TokenType::ONEWAY: 586 infAttr->SetValue(ASTAttr::ONEWAY); 587 break; 588 default: 589 LogError(__func__, __LINE__, attr, std::string("illegal attribute of interface")); 590 break; 591 } 592 } 593 594 if ((interfaceType == InterfaceType::HDI) && 595 (!infAttr->HasValue(ASTAttr::FULL) && !infAttr->HasValue(ASTAttr::LITE) && 596 !infAttr->HasValue(ASTAttr::MINI))) { 597 infAttr->SetValue(ASTAttr::FULL | ASTAttr::LITE | ASTAttr::MINI); 598 } 599 600 return infAttr; 601 } 602 CheckInterfaceAttr(const AutoPtr<ASTInterfaceType> & interface,Token token)603 void Parser::CheckInterfaceAttr(const AutoPtr<ASTInterfaceType> &interface, Token token) 604 { 605 bool ret = true; 606 std::string systemName; 607 switch (Options::GetInstance().GetSystemLevel()) { 608 case SystemLevel::FULL: 609 systemName = "full"; 610 ret = interface->IsFull(); 611 break; 612 case SystemLevel::LITE: 613 systemName = "lite"; 614 ret = interface->IsLite(); 615 break; 616 case SystemLevel::MINI: 617 systemName = "mini"; 618 ret = interface->IsMini(); 619 break; 620 default: 621 break; 622 } 623 624 if (!ret) { 625 LogError(__func__, __LINE__, token, StringHelper::Format("the system option is '%s', but the '%s' interface " 626 "has no '%s' attribute", systemName.c_str(), interface->GetName().c_str(), systemName.c_str())); 627 } 628 } 629 ParseInterfaceExternal(const AutoPtr<ASTInterfaceType> & interface)630 void Parser::ParseInterfaceExternal(const AutoPtr<ASTInterfaceType> &interface) 631 { 632 Token token = lexer_.PeekToken(); 633 lexer_.GetToken(); 634 if (interface->IsAttributeNone()) { 635 interface->SetExternal(true); 636 } else { 637 LogError(__func__, __LINE__, token, std::string("interface forward declaration should not have attribute.")); 638 } 639 } 640 ParseInterfaceBody(const AutoPtr<ASTInterfaceType> & interface)641 void Parser::ParseInterfaceBody(const AutoPtr<ASTInterfaceType> &interface) 642 { 643 Token token = lexer_.PeekToken(); 644 // expect symbol "{" or ";" 645 if (token.kind != TokenType::BRACES_LEFT) { 646 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '{'")); 647 } else { 648 lexer_.GetToken(); 649 } 650 651 // parse method 652 token = lexer_.PeekToken(); 653 while (token.kind != TokenType::BRACES_RIGHT && token.kind != TokenType::END_OF_FILE) { 654 AutoPtr<ASTMethod> method = ParseMethod(interface); 655 interface->AddMethod(method); 656 token = lexer_.PeekToken(); 657 } 658 659 // expect symbol "}" 660 token = lexer_.PeekToken(); 661 if (token.kind != TokenType::BRACES_RIGHT) { 662 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '}'")); 663 } else { 664 lexer_.GetToken(); 665 } 666 667 // expect symbol ";" 668 token = lexer_.PeekToken(); 669 if (token.kind == TokenType::SEMICOLON) { 670 lexer_.GetToken(); 671 } 672 673 interface->AddVersionMethod(CreateGetVersionMethod()); 674 } 675 ParseMethod(const AutoPtr<ASTInterfaceType> & interface)676 AutoPtr<ASTMethod> Parser::ParseMethod(const AutoPtr<ASTInterfaceType> &interface) 677 { 678 freezecontrolAttr_ = ""; 679 AutoPtr<ASTMethod> method = new ASTMethod(); 680 AutoPtr<ASTAttr> methodAttr = ParseMethodAttr(); 681 method->SetAttribute(methodAttr); 682 method->SetCacheable(methodAttr); 683 method->SetReturnType(ParseMethodReturnType()); 684 685 // parser method name 686 Token token = lexer_.PeekToken(); 687 if (token.kind != TokenType::ID) { 688 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected method name")); 689 } else { 690 method->SetName(token.value); 691 lexer_.GetToken(); 692 } 693 694 CheckMethodAttr(interface, method); 695 // (param1, param2, ...) 696 ParseMethodParamList(method); 697 698 // parse symbol ";" 699 token = lexer_.PeekToken(); 700 if (token.kind != TokenType::SEMICOLON) { 701 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ';'")); 702 } else { 703 lexer_.GetToken(); 704 } 705 706 size_t methodsCount = interface->GetMethodNumber() + 1; 707 AutoPtr<ASTInterfaceType> extInterface = interface->GetExtendsInterface(); 708 while (extInterface != nullptr) { 709 methodsCount += extInterface->GetMethodNumber(); 710 extInterface = extInterface->GetExtendsInterface(); 711 } 712 method->SetCmdId(methodsCount); 713 method->CheckOverload(interface); 714 715 if (!freezecontrolAttr_.empty()) { 716 method->SetFreezeControlReason(freezecontrolAttr_); 717 } 718 719 return method; 720 } 721 ParseMethodReturnType()722 AutoPtr<ASTType> Parser::ParseMethodReturnType() 723 { 724 if (Options::GetInstance().GetInterfaceType() == InterfaceType::HDI) { 725 return nullptr; 726 } 727 Token token = lexer_.PeekToken(); 728 if (token.kind == TokenType::ID && ast_->FindType(token.value) == nullptr) { 729 return nullptr; 730 } 731 // parse method return type, maybe not exist 732 if (CheckBasicType(token) || CheckUserDefType(token) || token.kind == TokenType::LIST || 733 token.kind == TokenType::MAP || token.kind == TokenType::SMQ) { 734 return ParseType(); 735 } 736 return nullptr; 737 } 738 ParseMethodAttr()739 AutoPtr<ASTAttr> Parser::ParseMethodAttr() 740 { 741 if (lexer_.PeekToken().kind != TokenType::BRACKETS_LEFT) { 742 return new ASTAttr(); 743 } 744 745 AttrSet attrs = ParseAttributeInfo(); 746 AutoPtr<ASTAttr> methodAttr = new ASTAttr(); 747 748 for (const auto &attr : attrs) { 749 switch (attr.kind) { 750 case TokenType::FULL: 751 methodAttr->SetValue(ASTAttr::FULL); 752 break; 753 case TokenType::LITE: 754 methodAttr->SetValue(ASTAttr::LITE); 755 break; 756 case TokenType::MINI: 757 methodAttr->SetValue(ASTAttr::MINI); 758 break; 759 case TokenType::ONEWAY: 760 methodAttr->SetValue(ASTAttr::ONEWAY); 761 break; 762 case TokenType::CACHEABLE: 763 methodAttr->SetValue(ASTAttr::CACHEABLE); 764 methodAttr->SetCacheableTimeString(attr.value); 765 break; 766 case TokenType::FREEZECONTROL: 767 methodAttr->SetValue(ASTAttr::FREEZECONTROL); 768 break; 769 default: 770 LogError(__func__, __LINE__, attr, std::string("illegal attribute of interface")); 771 break; 772 } 773 } 774 775 return methodAttr; 776 } 777 CreateGetVersionMethod()778 AutoPtr<ASTMethod> Parser::CreateGetVersionMethod() 779 { 780 AutoPtr<ASTMethod> method = new ASTMethod(); 781 method->SetName("GetVersion"); 782 783 AutoPtr<ASTType> type = ast_->FindType("unsigned int"); 784 if (type == nullptr) { 785 type = new ASTUintType(); 786 } 787 788 method->AddParameter(new ASTParameter("majorVer", ASTParamAttr::PARAM_OUT, type)); 789 method->AddParameter(new ASTParameter("minorVer", ASTParamAttr::PARAM_OUT, type)); 790 return method; 791 } 792 CheckMethodAttr(const AutoPtr<ASTInterfaceType> & interface,const AutoPtr<ASTMethod> & method)793 void Parser::CheckMethodAttr(const AutoPtr<ASTInterfaceType> &interface, const AutoPtr<ASTMethod> &method) 794 { 795 // if the attribute of method is empty, the default value is attribute of interface 796 if (!method->IsMini() && !method->IsLite() && !method->IsFull()) { 797 method->SetAttribute(interface->GetAttribute()); 798 } 799 800 if (!interface->IsMini() && method->IsMini()) { 801 LogError(__func__, __LINE__, StringHelper::Format("the '%s' method can not have 'mini' attribute, because the " 802 "'%s' interface has no 'mini' attribute", method->GetName().c_str(), interface->GetName().c_str())); 803 } 804 805 if (!interface->IsLite() && method->IsLite()) { 806 LogError(__func__, __LINE__, StringHelper::Format("the '%s' method can not have 'lite' attribute, because the " 807 "'%s' interface has no 'lite' attribute", method->GetName().c_str(), interface->GetName().c_str())); 808 } 809 810 if (!interface->IsFull() && method->IsFull()) { 811 LogError(__func__, __LINE__, StringHelper::Format("the '%s' method can not have 'full' attribute, because the " 812 "'%s' interface has no 'full' attribute", method->GetName().c_str(), interface->GetName().c_str())); 813 } 814 815 // the method has 'oneway' attribute if interface or method has 'oneway' attribute 816 if (interface->IsOneWay() || method->IsOneWay()) { 817 method->GetAttribute()->SetValue(ASTAttr::ONEWAY); 818 } 819 } 820 ParseMethodParamList(const AutoPtr<ASTMethod> & method)821 void Parser::ParseMethodParamList(const AutoPtr<ASTMethod> &method) 822 { 823 // ( 824 Token token = lexer_.PeekToken(); 825 if (token.kind != TokenType::PARENTHESES_LEFT) { 826 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '('")); 827 } else { 828 lexer_.GetToken(); 829 } 830 831 // () 832 token = lexer_.PeekToken(); 833 if (token.kind == TokenType::PARENTHESES_RIGHT) { 834 lexer_.GetToken(); 835 return; 836 } 837 838 // param 839 while (token.kind != TokenType::PARENTHESES_RIGHT && token.kind != TokenType::END_OF_FILE) { 840 AutoPtr<ASTParameter> param = ParseParam(); 841 if (method->IsOneWay() && (param->GetAttribute() & ASTParamAttr::PARAM_OUT)) { 842 LogError(__func__, __LINE__, token, StringHelper::Format("the '%s' parameter of '%s' method " 843 "can not be 'out'", param->GetName().c_str(), method->GetName().c_str())); 844 } 845 method->AddParameter(param); 846 847 // , 848 token = lexer_.PeekToken(); 849 if (token.kind == TokenType::COMMA) { 850 lexer_.GetToken(); 851 token = lexer_.PeekToken(); 852 if (token.kind == TokenType::PARENTHESES_RIGHT) { 853 LogError(__func__, __LINE__, token, std::string("")); 854 } 855 continue; 856 } 857 858 // ) 859 if (token.kind == TokenType::PARENTHESES_RIGHT) { 860 lexer_.GetToken(); 861 } else { 862 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ',' or ')'")); 863 lexer_.SkipToken(TokenType::PARENTHESES_RIGHT); 864 } 865 break; 866 } 867 } 868 ParseParam()869 AutoPtr<ASTParameter> Parser::ParseParam() 870 { 871 AutoPtr<ASTParamAttr> paramAttr = ParseParamAttr(); 872 AutoPtr<ASTType> paramType = ParseType(); 873 std::string paramName = ""; 874 875 // param name 876 Token token = lexer_.PeekToken(); 877 if (token.kind != TokenType::ID) { 878 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected param name")); 879 } else { 880 paramName = token.value; 881 lexer_.GetToken(); 882 } 883 884 if (paramType != nullptr && paramType->IsInterfaceType()) { 885 AutoPtr<ASTInterfaceType> ifaceType = dynamic_cast<ASTInterfaceType *>(paramType.Get()); 886 if (!ifaceType->IsCallback()) { 887 ifaceType->SetSerializable(true); 888 } 889 } 890 891 return new ASTParameter(paramName, paramAttr, paramType); 892 } 893 ParseParamAttr()894 AutoPtr<ASTParamAttr> Parser::ParseParamAttr() 895 { 896 AutoPtr<ASTParamAttr> attr = new ASTParamAttr(ASTParamAttr::PARAM_NONE); 897 898 if (!CheckParamAttr()) { 899 return attr; 900 } 901 902 // [in], [out], [inout], [in, out] 903 Token token = lexer_.PeekToken(); 904 while (token.kind != TokenType::BRACKETS_RIGHT && token.kind != TokenType::END_OF_FILE) { 905 SetParamAttrVal(token, attr); 906 907 // , 908 token = lexer_.PeekToken(); 909 if (token.kind == TokenType::COMMA) { 910 lexer_.GetToken(); 911 token = lexer_.PeekToken(); 912 continue; 913 } 914 915 // ] 916 if (token.kind != TokenType::BRACKETS_RIGHT) { 917 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ']'")); 918 while (token.kind != TokenType::COMMA && token.kind != TokenType::PARENTHESES_RIGHT && 919 token.kind != TokenType::END_OF_FILE) { 920 lexer_.GetToken(); 921 token = lexer_.PeekToken(); 922 } 923 return attr; 924 } 925 } 926 if (attr->value_ == ASTParamAttr::PARAM_NONE) { 927 attr->value_ |= ASTParamAttr::PARAM_IN; 928 } 929 lexer_.GetToken(); 930 931 return attr; 932 } 933 CheckParamAttr()934 bool Parser::CheckParamAttr() 935 { 936 Token token = lexer_.PeekToken(); 937 if (token.kind != TokenType::BRACKETS_LEFT) { 938 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '['")); 939 while (token.kind != TokenType::COMMA && token.kind != TokenType::PARENTHESES_RIGHT && 940 token.kind != TokenType::END_OF_FILE) { 941 lexer_.GetToken(); 942 token = lexer_.PeekToken(); 943 } 944 return false; 945 } 946 lexer_.GetToken(); 947 return true; 948 } 949 SetParamAttrVal(Token token,AutoPtr<ASTParamAttr> attr)950 void Parser::SetParamAttrVal(Token token, AutoPtr<ASTParamAttr> attr) 951 { 952 switch (token.kind) { 953 case TokenType::IN: 954 attr->value_ |= ASTParamAttr::PARAM_IN; 955 break; 956 case TokenType::OUT: 957 attr->value_ |= ASTParamAttr::PARAM_OUT; 958 break; 959 case TokenType::INOUT: 960 attr->value_ |= ASTParamAttr::PARAM_INOUT; 961 break; 962 default: 963 LogErrorBeforeToken(__func__, __LINE__, token, 964 StringHelper::Format("expected 'in', 'out' or 'inout' attribute")); 965 return; 966 } 967 lexer_.GetToken(); 968 } 969 ParseType()970 AutoPtr<ASTType> Parser::ParseType() 971 { 972 AutoPtr<ASTType> type = nullptr; 973 Token token = lexer_.PeekToken(); 974 if (CheckBasicType(token)) { 975 type = ParseBasicType(); 976 } else if (CheckUserDefType(token)) { 977 type = ParseUserDefType(); 978 } else { 979 switch (token.kind) { 980 case TokenType::LIST: 981 type = ParseListType(); 982 break; 983 case TokenType::MAP: 984 type = ParseMapType(); 985 break; 986 case TokenType::SMQ: 987 type = ParseSmqType(); 988 break; 989 default: 990 LogError(__func__, __LINE__, token, StringHelper::Format("'%s' of type is illegal", 991 token.value.c_str())); 992 return nullptr; 993 } 994 } 995 996 if (type == nullptr) { 997 LogError(__func__, __LINE__, token, std::string("this type was not declared in this scope")); 998 } 999 if (!CheckType(token, type)) { 1000 return nullptr; 1001 } 1002 1003 while (lexer_.PeekToken().kind == TokenType::BRACKETS_LEFT) { 1004 type = ParseArrayType(type); 1005 } 1006 return type; 1007 } 1008 CheckBasicType(Token token)1009 bool Parser::CheckBasicType(Token token) 1010 { 1011 switch (token.kind) { 1012 case TokenType::VOID: 1013 case TokenType::BOOLEAN: 1014 case TokenType::BYTE: 1015 case TokenType::SHORT: 1016 case TokenType::INT: 1017 case TokenType::LONG: 1018 case TokenType::STRING: 1019 case TokenType::STRING16: 1020 case TokenType::FLOAT: 1021 case TokenType::DOUBLE: 1022 case TokenType::FD: 1023 case TokenType::ASHMEM: 1024 case TokenType::NATIVE_BUFFER: 1025 case TokenType::POINTER: 1026 case TokenType::UNSIGNED: 1027 case TokenType::CHAR: 1028 return true; 1029 default: 1030 return false; 1031 } 1032 } 1033 ParseBasicType()1034 AutoPtr<ASTType> Parser::ParseBasicType() 1035 { 1036 AutoPtr<ASTType> type = nullptr; 1037 Token token = lexer_.PeekToken(); 1038 if (token.kind == TokenType::UNSIGNED) { 1039 type = ParseUnsignedType(); 1040 } else { 1041 type = ast_->FindType(token.value); 1042 lexer_.GetToken(); 1043 } 1044 1045 ast_->AddType(type); 1046 return type; 1047 } 1048 ParseUnsignedType()1049 AutoPtr<ASTType> Parser::ParseUnsignedType() 1050 { 1051 AutoPtr<ASTType> type = nullptr; 1052 std::string namePrefix = lexer_.GetToken().value; 1053 Token token = lexer_.PeekToken(); 1054 switch (token.kind) { 1055 case TokenType::CHAR: 1056 case TokenType::SHORT: 1057 case TokenType::INT: 1058 case TokenType::LONG: 1059 type = ast_->FindType(namePrefix + " " + token.value); 1060 lexer_.GetToken(); 1061 break; 1062 default: 1063 LogError(__func__, __LINE__, token, 1064 StringHelper::Format("'unsigned %s' was not declared in the idl file", token.value.c_str())); 1065 break; 1066 } 1067 return type; 1068 } 1069 ParseArrayType(const AutoPtr<ASTType> & elementType)1070 AutoPtr<ASTType> Parser::ParseArrayType(const AutoPtr<ASTType> &elementType) 1071 { 1072 lexer_.GetToken(); // '[' 1073 1074 Token token = lexer_.PeekToken(); 1075 if (token.kind != TokenType::BRACKETS_RIGHT) { 1076 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ']'")); 1077 return nullptr; 1078 } 1079 lexer_.GetToken(); // ']' 1080 1081 if (elementType == nullptr) { 1082 return nullptr; 1083 } 1084 1085 AutoPtr<ASTArrayType> arrayType = new ASTArrayType(); 1086 arrayType->SetElementType(elementType); 1087 AutoPtr<ASTType> retType = ast_->FindType(arrayType->ToString(), false); 1088 if (retType == nullptr) { 1089 retType = arrayType.Get(); 1090 ast_->AddType(retType); 1091 } 1092 return retType; 1093 } 1094 ParseListType()1095 AutoPtr<ASTType> Parser::ParseListType() 1096 { 1097 lexer_.GetToken(); // List 1098 1099 Token token = lexer_.PeekToken(); 1100 if (token.kind != TokenType::ANGLE_BRACKETS_LEFT) { 1101 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '<'")); 1102 } else { 1103 lexer_.GetToken(); // '<' 1104 } 1105 1106 AutoPtr<ASTType> type = ParseType(); // element type 1107 if (type == nullptr) { 1108 lexer_.SkipToken(TokenType::ANGLE_BRACKETS_RIGHT); 1109 return nullptr; 1110 } 1111 1112 token = lexer_.PeekToken(); 1113 if (token.kind != TokenType::ANGLE_BRACKETS_RIGHT) { 1114 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '>'")); 1115 } else { 1116 lexer_.GetToken(); // '>' 1117 } 1118 1119 AutoPtr<ASTListType> listType = new ASTListType(); 1120 listType->SetElementType(type); 1121 AutoPtr<ASTType> retType = ast_->FindType(listType->ToString(), false); 1122 if (retType == nullptr) { 1123 retType = listType.Get(); 1124 ast_->AddType(retType); 1125 } 1126 return retType; 1127 } 1128 ParseMapType()1129 AutoPtr<ASTType> Parser::ParseMapType() 1130 { 1131 lexer_.GetToken(); // 'Map' 1132 1133 Token token = lexer_.PeekToken(); 1134 if (token.kind != TokenType::ANGLE_BRACKETS_LEFT) { 1135 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '<'")); 1136 } else { 1137 lexer_.GetToken(); // '<' 1138 } 1139 1140 AutoPtr<ASTType> keyType = ParseType(); // key type 1141 if (keyType == nullptr) { 1142 LogError(__func__, __LINE__, token, StringHelper::Format("key type '%s' is illegal", token.value.c_str())); 1143 lexer_.SkipToken(TokenType::ANGLE_BRACKETS_RIGHT); 1144 return nullptr; 1145 } 1146 1147 token = lexer_.PeekToken(); 1148 if (token.kind != TokenType::COMMA) { 1149 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ','")); 1150 } else { 1151 lexer_.GetToken(); // ',' 1152 } 1153 1154 AutoPtr<ASTType> valueType = ParseType(); 1155 if (valueType == nullptr) { 1156 LogError(__func__, __LINE__, token, StringHelper::Format("value type '%s' is illegal", token.value.c_str())); 1157 lexer_.SkipToken(TokenType::ANGLE_BRACKETS_RIGHT); 1158 return nullptr; 1159 } 1160 1161 token = lexer_.PeekToken(); 1162 if (token.kind != TokenType::ANGLE_BRACKETS_RIGHT) { 1163 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '>'")); 1164 } else { 1165 lexer_.GetToken(); 1166 } 1167 1168 AutoPtr<ASTMapType> mapType = new ASTMapType(); 1169 mapType->SetKeyType(keyType); 1170 mapType->SetValueType(valueType); 1171 AutoPtr<ASTType> retType = ast_->FindType(mapType->ToString(), false); 1172 if (retType == nullptr) { 1173 retType = mapType.Get(); 1174 ast_->AddType(retType); 1175 } 1176 return retType; 1177 } 1178 ParseSmqType()1179 AutoPtr<ASTType> Parser::ParseSmqType() 1180 { 1181 lexer_.GetToken(); // 'SharedMemQueue' 1182 1183 Token token = lexer_.PeekToken(); 1184 if (token.kind != TokenType::ANGLE_BRACKETS_LEFT) { 1185 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '<'")); 1186 } else { 1187 lexer_.GetToken(); // '<' 1188 } 1189 1190 AutoPtr<ASTType> innerType = ParseType(); 1191 if (innerType == nullptr) { 1192 lexer_.SkipToken(TokenType::ANGLE_BRACKETS_RIGHT); 1193 return nullptr; 1194 } 1195 1196 token = lexer_.PeekToken(); 1197 if (token.kind != TokenType::ANGLE_BRACKETS_RIGHT) { 1198 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '>'")); 1199 } else { 1200 lexer_.GetToken(); // '>' 1201 } 1202 1203 AutoPtr<ASTSmqType> smqType = new ASTSmqType(); 1204 smqType->SetInnerType(innerType); 1205 AutoPtr<ASTType> retType = smqType.Get(); 1206 ast_->AddType(retType); 1207 return retType; 1208 } 1209 CheckUserDefType(Token token)1210 bool Parser::CheckUserDefType(Token token) 1211 { 1212 switch (token.kind) { 1213 case TokenType::ENUM: 1214 case TokenType::STRUCT: 1215 case TokenType::UNION: 1216 case TokenType::ID: 1217 case TokenType::SEQ: 1218 return true; 1219 default: 1220 return false; 1221 } 1222 } 1223 ParseUserDefType()1224 AutoPtr<ASTType> Parser::ParseUserDefType() 1225 { 1226 Token token = lexer_.GetToken(); 1227 if (token.kind == TokenType::ID) { 1228 return ast_->FindType(token.value); 1229 } 1230 1231 token = lexer_.PeekToken(); 1232 if (token.kind != TokenType::ID) { 1233 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected identifier")); 1234 return nullptr; 1235 } 1236 lexer_.GetToken(); 1237 AutoPtr<ASTType> type = ast_->FindType(token.value); 1238 ast_->AddType(type); 1239 return type; 1240 } 1241 ParseEnumDeclaration(const AttrSet & attrs)1242 void Parser::ParseEnumDeclaration(const AttrSet &attrs) 1243 { 1244 AutoPtr<ASTEnumType> enumType = new ASTEnumType; 1245 g_currentEnum = enumType; 1246 enumType->SetAttribute(ParseUserDefTypeAttr(attrs)); 1247 1248 lexer_.GetToken(); 1249 Token token = lexer_.PeekToken(); 1250 if (token.kind != TokenType::ID) { 1251 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected enum type name")); 1252 } else { 1253 lexer_.GetToken(); 1254 enumType->SetName(token.value); 1255 } 1256 1257 token = lexer_.PeekToken(); 1258 if (token.kind == TokenType::COLON || token.kind == TokenType::BRACES_LEFT) { 1259 enumType->SetBaseType(ParseEnumBaseType()); 1260 } else { 1261 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ':' or '{'")); 1262 } 1263 1264 ParserEnumMember(enumType); 1265 token = lexer_.PeekToken(); 1266 if (token.kind != TokenType::BRACES_RIGHT) { 1267 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '}'")); 1268 return; 1269 } else { 1270 lexer_.GetToken(); 1271 } 1272 1273 token = lexer_.PeekToken(); 1274 if (token.kind != TokenType::SEMICOLON) { 1275 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ';'")); 1276 } else { 1277 lexer_.GetToken(); 1278 } 1279 1280 enumType->SetNamespace(ast_->ParseNamespace(ast_->GetFullName())); 1281 ast_->AddTypeDefinition(enumType.Get()); 1282 g_currentEnum = nullptr; 1283 } 1284 ParseEnumBaseType()1285 AutoPtr<ASTType> Parser::ParseEnumBaseType() 1286 { 1287 Token token = lexer_.PeekToken(); 1288 lexer_.GetToken(); 1289 if (token.kind != TokenType::COLON) { 1290 return ast_->FindType("int"); 1291 } 1292 1293 token = lexer_.PeekToken(); 1294 AutoPtr<ASTType> baseType = ParseType(); 1295 if (baseType != nullptr) { 1296 switch (baseType->GetTypeKind()) { 1297 case TypeKind::TYPE_BYTE: 1298 case TypeKind::TYPE_SHORT: 1299 case TypeKind::TYPE_INT: 1300 case TypeKind::TYPE_LONG: 1301 case TypeKind::TYPE_UCHAR: 1302 case TypeKind::TYPE_USHORT: 1303 case TypeKind::TYPE_UINT: 1304 case TypeKind::TYPE_ULONG: 1305 case TypeKind::TYPE_ENUM: 1306 break; 1307 default: { 1308 LogError(__func__, __LINE__, token, std::string("illegal base type of enum")); 1309 lexer_.SkipUntilToken(TokenType::BRACES_LEFT); 1310 break; 1311 } 1312 } 1313 } 1314 1315 token = lexer_.PeekToken(); 1316 if (token.kind != TokenType::BRACES_LEFT) { 1317 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '{'")); 1318 } 1319 lexer_.GetToken(); 1320 return baseType; 1321 } 1322 ParserEnumMember(const AutoPtr<ASTEnumType> & enumType)1323 void Parser::ParserEnumMember(const AutoPtr<ASTEnumType> &enumType) 1324 { 1325 while (lexer_.PeekToken().kind == TokenType::ID) { 1326 Token token = lexer_.GetToken(); 1327 AutoPtr<ASTEnumValue> enumValue = new ASTEnumValue(token.value); 1328 1329 token = lexer_.PeekToken(); 1330 if (token.kind == TokenType::ASSIGN) { 1331 lexer_.GetToken(); 1332 enumValue->SetExprValue(ParseExpr()); 1333 } 1334 1335 enumValue->SetType(enumType->GetBaseType()); 1336 if (!enumType->AddMember(enumValue)) { 1337 LogError(__func__, __LINE__, StringHelper::Format("AddMemberException:member '%s' already exists !", 1338 enumValue->GetName().c_str())); 1339 } 1340 token = lexer_.PeekToken(); 1341 if (token.kind == TokenType::COMMA) { 1342 lexer_.GetToken(); 1343 continue; 1344 } 1345 1346 if (token.kind != TokenType::BRACES_RIGHT) { 1347 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ',' or '}'")); 1348 } 1349 } 1350 } 1351 ParseStructDeclaration(const AttrSet & attrs)1352 void Parser::ParseStructDeclaration(const AttrSet &attrs) 1353 { 1354 AutoPtr<ASTStructType> structType = new ASTStructType; 1355 structType->SetAttribute(ParseUserDefTypeAttr(attrs)); 1356 1357 lexer_.GetToken(); 1358 Token token = lexer_.PeekToken(); 1359 if (token.kind != TokenType::ID) { 1360 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected struct name")); 1361 } else { 1362 structType->SetName(token.value); 1363 lexer_.GetToken(); 1364 } 1365 1366 token = lexer_.PeekToken(); 1367 if (token.kind == TokenType::COLON) { 1368 AutoPtr<ASTStructType> parentType = ParseStructParentType(); 1369 structType->SetParentType(parentType); 1370 } else if (token.kind != TokenType::BRACES_LEFT) { 1371 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '{'")); 1372 } else { 1373 lexer_.GetToken(); 1374 } 1375 1376 ParseStructMember(structType); 1377 1378 token = lexer_.PeekToken(); 1379 if (token.kind != TokenType::BRACES_RIGHT) { 1380 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '}'")); 1381 } else { 1382 lexer_.GetToken(); 1383 } 1384 1385 token = lexer_.PeekToken(); 1386 if (token.kind != TokenType::SEMICOLON) { 1387 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ';'")); 1388 } else { 1389 lexer_.GetToken(); 1390 } 1391 1392 structType->SetNamespace(ast_->ParseNamespace(ast_->GetFullName())); 1393 ast_->AddTypeDefinition(structType.Get()); 1394 } 1395 ParseStructParentType()1396 AutoPtr<ASTStructType> Parser::ParseStructParentType() 1397 { 1398 lexer_.GetToken(); 1399 Token token = lexer_.PeekToken(); 1400 AutoPtr<ASTType> baseType = ParseType(); 1401 if (baseType == nullptr) { 1402 LogError(__func__, __LINE__, token, std::string("expected base type name before '{' token")); 1403 return nullptr; 1404 } 1405 1406 if (baseType->GetTypeKind() != TypeKind::TYPE_STRUCT) { 1407 LogError(__func__, __LINE__, token, StringHelper::Format("illegal base type of struct: '%s'", 1408 baseType->ToString().c_str())); 1409 lexer_.SkipUntilToken(TokenType::BRACES_LEFT); 1410 } 1411 1412 token = lexer_.PeekToken(); 1413 if (token.kind != TokenType::BRACES_LEFT) { 1414 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '{'")); 1415 } 1416 lexer_.GetToken(); 1417 return dynamic_cast<ASTStructType *>(baseType.Get()); 1418 } 1419 ParseStructMember(const AutoPtr<ASTStructType> & structType)1420 void Parser::ParseStructMember(const AutoPtr<ASTStructType> &structType) 1421 { 1422 Token token = lexer_.PeekToken(); 1423 while (token.kind != TokenType::BRACES_RIGHT && token.kind != TokenType::END_OF_FILE) { 1424 AutoPtr<ASTType> memberType = ParseType(); 1425 if (memberType == nullptr) { 1426 lexer_.SkipToken(TokenType::SEMICOLON); 1427 token = lexer_.PeekToken(); 1428 continue; 1429 } 1430 1431 token = lexer_.PeekToken(); 1432 if (token.kind != TokenType::ID) { 1433 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected member name")); 1434 lexer_.SkipToken(TokenType::SEMICOLON); 1435 token = lexer_.PeekToken(); 1436 continue; 1437 } 1438 1439 lexer_.GetToken(); 1440 std::string memberName = token.value; 1441 structType->AddMember(memberType, memberName); 1442 1443 token = lexer_.PeekToken(); 1444 if (token.kind == TokenType::SEMICOLON) { 1445 lexer_.GetToken(); 1446 token = lexer_.PeekToken(); 1447 continue; 1448 } 1449 1450 if (token.kind != TokenType::BRACES_RIGHT) { 1451 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ',' or '}'")); 1452 } 1453 } 1454 } 1455 ParseUnionDeclaration(const AttrSet & attrs)1456 void Parser::ParseUnionDeclaration(const AttrSet &attrs) 1457 { 1458 AutoPtr<ASTUnionType> unionType = new ASTUnionType; 1459 unionType->SetAttribute(ParseUserDefTypeAttr(attrs)); 1460 1461 lexer_.GetToken(); 1462 Token token = lexer_.PeekToken(); 1463 if (token.kind != TokenType::ID) { 1464 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected struct name")); 1465 } else { 1466 unionType->SetName(token.value); 1467 lexer_.GetToken(); 1468 } 1469 1470 token = lexer_.PeekToken(); 1471 if (token.kind != TokenType::BRACES_LEFT) { 1472 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '{'")); 1473 } else { 1474 lexer_.GetToken(); 1475 } 1476 1477 ParseUnionMember(unionType); 1478 1479 token = lexer_.PeekToken(); 1480 if (token.kind != TokenType::BRACES_RIGHT) { 1481 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '}'")); 1482 } else { 1483 lexer_.GetToken(); 1484 } 1485 1486 token = lexer_.PeekToken(); 1487 if (token.kind != TokenType::SEMICOLON) { 1488 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ';'")); 1489 } else { 1490 lexer_.GetToken(); 1491 } 1492 1493 unionType->SetNamespace(ast_->ParseNamespace(ast_->GetFullName())); 1494 ast_->AddTypeDefinition(unionType.Get()); 1495 } 1496 ParseUnionMember(const AutoPtr<ASTUnionType> & unionType)1497 void Parser::ParseUnionMember(const AutoPtr<ASTUnionType> &unionType) 1498 { 1499 Token token = lexer_.PeekToken(); 1500 while (token.kind != TokenType::BRACES_RIGHT && token.kind != TokenType::END_OF_FILE) { 1501 AutoPtr<ASTType> memberType = ParseType(); 1502 if (memberType == nullptr) { 1503 lexer_.SkipToken(TokenType::SEMICOLON); 1504 token = lexer_.PeekToken(); 1505 continue; 1506 } 1507 1508 token = lexer_.PeekToken(); 1509 if (token.kind != TokenType::ID) { 1510 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected member name")); 1511 lexer_.SkipToken(TokenType::SEMICOLON); 1512 token = lexer_.PeekToken(); 1513 continue; 1514 } 1515 lexer_.GetToken(); 1516 1517 std::string memberName = token.value; 1518 if (!AddUnionMember(unionType, memberType, memberName)) { 1519 LogError(__func__, __LINE__, token, StringHelper::Format( 1520 "union not support this type or name of member duplicate '%s'", token.value.c_str())); 1521 } 1522 1523 token = lexer_.PeekToken(); 1524 if (token.kind == TokenType::SEMICOLON) { 1525 lexer_.GetToken(); 1526 token = lexer_.PeekToken(); 1527 continue; 1528 } 1529 1530 if (token.kind != TokenType::BRACES_RIGHT) { 1531 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ',' or '}'")); 1532 } 1533 } 1534 } 1535 AddUnionMember(const AutoPtr<ASTUnionType> & unionType,const AutoPtr<ASTType> & type,const std::string & name) const1536 bool Parser::AddUnionMember( 1537 const AutoPtr<ASTUnionType> &unionType, const AutoPtr<ASTType> &type, const std::string &name) const 1538 { 1539 for (size_t i = 0; i < unionType->GetMemberNumber(); i++) { 1540 if (name == unionType->GetMemberName(i)) { 1541 return false; 1542 } 1543 } 1544 1545 // Non pod type members are not allowed in the union 1546 if (!type->IsPod()) { 1547 return false; 1548 } 1549 1550 unionType->AddMember(type, name); 1551 return true; 1552 } 1553 ParseUserDefTypeAttr(const AttrSet & attrs)1554 AutoPtr<ASTAttr> Parser::ParseUserDefTypeAttr(const AttrSet &attrs) 1555 { 1556 AutoPtr<ASTAttr> attr = new ASTAttr(); 1557 for (const auto &token : attrs) { 1558 switch (token.kind) { 1559 case TokenType::FULL: 1560 attr->SetValue(ASTAttr::FULL); 1561 break; 1562 case TokenType::LITE: 1563 attr->SetValue(ASTAttr::LITE); 1564 break; 1565 case TokenType::MINI: 1566 attr->SetValue(ASTAttr::MINI); 1567 break; 1568 default: 1569 LogError(__func__, __LINE__, token, StringHelper::Format("invalid attribute '%s' for type decl", 1570 token.value.c_str())); 1571 break; 1572 } 1573 } 1574 1575 if (attr->IsNone()) { 1576 attr->SetValue(ASTAttr::FULL | ASTAttr::LITE | ASTAttr::MINI); 1577 } 1578 1579 return attr; 1580 } 1581 ParseExpr()1582 AutoPtr<ASTExpr> Parser::ParseExpr() 1583 { 1584 lexer_.SetParseMode(Lexer::ParseMode::EXPR_MODE); 1585 AutoPtr<ASTExpr> value = ParseAndExpr(); 1586 lexer_.SetParseMode(Lexer::ParseMode::DECL_MODE); 1587 return value; 1588 } 1589 ParseAndExpr()1590 AutoPtr<ASTExpr> Parser::ParseAndExpr() 1591 { 1592 AutoPtr<ASTExpr> left = ParseXorExpr(); 1593 Token token = lexer_.PeekToken(); 1594 while (token.kind == TokenType::AND) { 1595 lexer_.GetToken(); 1596 AutoPtr<ASTBinaryExpr> expr = new ASTBinaryExpr; 1597 expr->op_ = BinaryOpKind::AND; 1598 expr->lExpr_ = left; 1599 expr->rExpr_ = ParseXorExpr(); 1600 1601 left = expr.Get(); 1602 token = lexer_.PeekToken(); 1603 } 1604 return left; 1605 } 1606 ParseXorExpr()1607 AutoPtr<ASTExpr> Parser::ParseXorExpr() 1608 { 1609 AutoPtr<ASTExpr> left = ParseOrExpr(); 1610 Token token = lexer_.PeekToken(); 1611 while (token.kind == TokenType::XOR) { 1612 lexer_.GetToken(); 1613 AutoPtr<ASTBinaryExpr> expr = new ASTBinaryExpr; 1614 expr->op_ = BinaryOpKind::XOR; 1615 expr->lExpr_ = left; 1616 expr->rExpr_ = ParseOrExpr(); 1617 1618 left = expr.Get(); 1619 token = lexer_.PeekToken(); 1620 } 1621 return left; 1622 } 1623 ParseOrExpr()1624 AutoPtr<ASTExpr> Parser::ParseOrExpr() 1625 { 1626 AutoPtr<ASTExpr> left = ParseShiftExpr(); 1627 Token token = lexer_.PeekToken(); 1628 while (token.kind == TokenType::OR) { 1629 lexer_.GetToken(); 1630 AutoPtr<ASTBinaryExpr> expr = new ASTBinaryExpr; 1631 expr->op_ = BinaryOpKind::OR; 1632 expr->lExpr_ = left; 1633 expr->rExpr_ = ParseShiftExpr(); 1634 1635 left = expr.Get(); 1636 token = lexer_.PeekToken(); 1637 } 1638 return left; 1639 } 1640 ParseShiftExpr()1641 AutoPtr<ASTExpr> Parser::ParseShiftExpr() 1642 { 1643 AutoPtr<ASTExpr> left = ParseAddExpr(); 1644 Token token = lexer_.PeekToken(); 1645 while (token.kind == TokenType::LEFT_SHIFT || token.kind == TokenType::RIGHT_SHIFT) { 1646 lexer_.GetToken(); 1647 BinaryOpKind op = (token.kind == TokenType::LEFT_SHIFT) ? BinaryOpKind::LSHIFT : BinaryOpKind::RSHIFT; 1648 AutoPtr<ASTBinaryExpr> expr = new ASTBinaryExpr; 1649 expr->op_ = op; 1650 expr->lExpr_ = left; 1651 expr->rExpr_ = ParseAddExpr(); 1652 1653 left = expr.Get(); 1654 token = lexer_.PeekToken(); 1655 } 1656 return left; 1657 } 1658 ParseAddExpr()1659 AutoPtr<ASTExpr> Parser::ParseAddExpr() 1660 { 1661 AutoPtr<ASTExpr> left = ParseMulExpr(); 1662 Token token = lexer_.PeekToken(); 1663 while (token.kind == TokenType::ADD || token.kind == TokenType::SUB) { 1664 lexer_.GetToken(); 1665 BinaryOpKind op = (token.kind == TokenType::ADD) ? BinaryOpKind::ADD : BinaryOpKind::SUB; 1666 AutoPtr<ASTBinaryExpr> expr = new ASTBinaryExpr; 1667 expr->op_ = op; 1668 expr->lExpr_ = left; 1669 expr->rExpr_ = ParseMulExpr(); 1670 1671 left = expr.Get(); 1672 token = lexer_.PeekToken(); 1673 } 1674 return left; 1675 } 1676 ParseMulExpr()1677 AutoPtr<ASTExpr> Parser::ParseMulExpr() 1678 { 1679 AutoPtr<ASTExpr> left = ParseUnaryExpr(); 1680 Token token = lexer_.PeekToken(); 1681 while ( 1682 token.kind == TokenType::STAR || token.kind == TokenType::SLASH || token.kind == TokenType::PERCENT_SIGN) { 1683 lexer_.GetToken(); 1684 BinaryOpKind op = BinaryOpKind::MUL; 1685 if (token.kind == TokenType::SLASH) { 1686 op = BinaryOpKind::DIV; 1687 } else if (token.kind == TokenType::PERCENT_SIGN) { 1688 op = BinaryOpKind::MOD; 1689 } 1690 AutoPtr<ASTBinaryExpr> expr = new ASTBinaryExpr; 1691 expr->op_ = op; 1692 expr->lExpr_ = left; 1693 expr->rExpr_ = ParseUnaryExpr(); 1694 1695 left = expr.Get(); 1696 token = lexer_.PeekToken(); 1697 } 1698 return left; 1699 } 1700 ParseUnaryExpr()1701 AutoPtr<ASTExpr> Parser::ParseUnaryExpr() 1702 { 1703 Token token = lexer_.PeekToken(); 1704 switch (token.kind) { 1705 case TokenType::ADD: 1706 case TokenType::SUB: 1707 case TokenType::TILDE: { 1708 lexer_.GetToken(); 1709 AutoPtr<ASTUnaryExpr> expr = new ASTUnaryExpr; 1710 expr->op_ = UnaryOpKind::PLUS; 1711 if (token.kind == TokenType::SUB) { 1712 expr->op_ = UnaryOpKind::MINUS; 1713 } else if (token.kind == TokenType::TILDE) { 1714 expr->op_ = UnaryOpKind::TILDE; 1715 } 1716 1717 expr->expr_ = ParseUnaryExpr(); 1718 return expr.Get(); 1719 } 1720 default: 1721 return ParsePrimaryExpr(); 1722 } 1723 } 1724 ParsePrimaryExpr()1725 AutoPtr<ASTExpr> Parser::ParsePrimaryExpr() 1726 { 1727 Token token = lexer_.PeekToken(); 1728 switch (token.kind) { 1729 case TokenType::PARENTHESES_LEFT: { 1730 lexer_.GetToken(); 1731 AutoPtr<ASTExpr> expr = ParseExpr(); 1732 token = lexer_.PeekToken(); 1733 if (token.kind != TokenType::PARENTHESES_RIGHT) { 1734 LogErrorBeforeToken(__func__, __LINE__, token, StringHelper::Format("expected ')'")); 1735 } else { 1736 lexer_.GetToken(); 1737 expr->isParenExpr = true; 1738 } 1739 return expr; 1740 } 1741 case TokenType::NUM: 1742 return ParseNumExpr(); 1743 case TokenType::ID: 1744 if (g_currentEnum == nullptr) { 1745 LogError(__func__, __LINE__, token, std::string("this expression is not supported")); 1746 lexer_.SkipUntilToken(TokenType::COMMA); 1747 return nullptr; 1748 } 1749 return ParseEnumExpr(); 1750 default: 1751 LogError(__func__, __LINE__, token, std::string("this expression is not supported")); 1752 lexer_.SkipUntilToken(TokenType::COMMA); 1753 return nullptr; 1754 } 1755 } 1756 ParseNumExpr()1757 AutoPtr<ASTExpr> Parser::ParseNumExpr() 1758 { 1759 Token token = lexer_.GetToken(); 1760 if (!CheckNumber(token.value)) { 1761 LogError(__func__, __LINE__, token, StringHelper::Format("unknown integer number: '%s'", token.value.c_str())); 1762 return nullptr; 1763 } 1764 1765 AutoPtr<ASTNumExpr> expr = new ASTNumExpr; 1766 expr->value_ = token.value; 1767 return expr.Get(); 1768 } 1769 ParseEnumExpr()1770 AutoPtr<ASTExpr> Parser::ParseEnumExpr() 1771 { 1772 Token token = lexer_.GetToken(); 1773 if (!g_currentEnum->HasMember(token.value)) { 1774 LogError(__func__, __LINE__, token, StringHelper::Format("unknown enum member: '%s'", token.value.c_str())); 1775 return nullptr; 1776 } 1777 1778 AutoPtr<ASTEnumExpr> expr = new ASTEnumExpr; 1779 expr->value_ = token.value; 1780 return expr.Get(); 1781 } 1782 CheckNumber(const std::string & integerVal) const1783 bool Parser::CheckNumber(const std::string& integerVal) const 1784 { 1785 if (std::regex_match(integerVal, RE_BIN_NUM) || std::regex_match(integerVal, RE_OCT_NUM)|| 1786 std::regex_match(integerVal, RE_DEC_NUM) || std::regex_match(integerVal, RE_HEX_NUM)) { 1787 return true; 1788 } 1789 return false; 1790 } 1791 CheckType(const Token & token,const AutoPtr<ASTType> & type)1792 bool Parser::CheckType(const Token &token, const AutoPtr<ASTType> &type) 1793 { 1794 if ((type == nullptr) || !CheckTypeByMode(token, type)) { 1795 return false; 1796 } 1797 1798 if (Options::GetInstance().GetLanguage() == Language::C) { 1799 if (type->IsSequenceableType() || type->IsSmqType() || type->IsAshmemType()) { 1800 LogError(__func__, __LINE__, token, StringHelper::Format("The %s type is not supported by c language.", 1801 type->ToString().c_str())); 1802 return false; 1803 } 1804 } else if (Options::GetInstance().GetLanguage() == Language::JAVA) { 1805 switch (type->GetTypeKind()) { 1806 case TypeKind::TYPE_UCHAR: 1807 case TypeKind::TYPE_USHORT: 1808 case TypeKind::TYPE_UINT: 1809 case TypeKind::TYPE_ULONG: 1810 case TypeKind::TYPE_ENUM: 1811 case TypeKind::TYPE_STRUCT: 1812 case TypeKind::TYPE_UNION: 1813 case TypeKind::TYPE_SMQ: 1814 case TypeKind::TYPE_UNKNOWN: 1815 LogError(__func__, __LINE__, token, StringHelper::Format("The '%s' type is not supported " 1816 "by java language.", type->ToString().c_str())); 1817 return false; 1818 default: 1819 break; 1820 } 1821 } 1822 1823 return true; 1824 } 1825 CheckTypeByMode(const Token & token,const AutoPtr<ASTType> & type)1826 bool Parser::CheckTypeByMode(const Token &token, const AutoPtr<ASTType> &type) 1827 { 1828 if (!Options::GetInstance().DoPassthrough() && type->IsPointerType()) { 1829 LogError(__func__, __LINE__, token, StringHelper::Format("The %s type is only supported by passthrough mode.", 1830 type->ToString().c_str())); 1831 return false; 1832 } 1833 1834 if (Options::GetInstance().DoGenerateKernelCode()) { 1835 switch (type->GetTypeKind()) { 1836 case TypeKind::TYPE_FLOAT: 1837 case TypeKind::TYPE_DOUBLE: 1838 case TypeKind::TYPE_FILEDESCRIPTOR: 1839 case TypeKind::TYPE_INTERFACE: 1840 case TypeKind::TYPE_SMQ: 1841 case TypeKind::TYPE_ASHMEM: 1842 case TypeKind::TYPE_NATIVE_BUFFER: 1843 case TypeKind::TYPE_POINTER: 1844 LogError(__func__, __LINE__, token, 1845 StringHelper::Format("The '%s' type is not supported by kernel mode.", type->ToString().c_str())); 1846 return false; 1847 default: 1848 break; 1849 } 1850 } 1851 return true; 1852 } 1853 SetAstFileType()1854 void Parser::SetAstFileType() 1855 { 1856 if (ast_->GetInterfaceDef() != nullptr) { 1857 if (ast_->GetInterfaceDef()->IsCallback()) { 1858 ast_->SetAStFileType(ASTFileType::AST_ICALLBACK); 1859 } else { 1860 ast_->SetAStFileType(ASTFileType::AST_IFACE); 1861 } 1862 } else { 1863 ast_->SetAStFileType(ASTFileType::AST_TYPES); 1864 } 1865 } 1866 1867 /* 1868 * filePath: ./ohos/interface/foo/v1_0/IFoo.idl 1869 * package OHOS.Hdi.foo.v1_0; 1870 */ CheckPackageName(const std::string & filePath,const std::string & packageName) const1871 bool Parser::CheckPackageName(const std::string &filePath, const std::string &packageName) const 1872 { 1873 std::string pkgToPath = Options::GetInstance().GetPackagePath(packageName); 1874 1875 size_t index = filePath.rfind(SEPARATOR); 1876 if (index == std::string::npos) { 1877 return false; 1878 } 1879 1880 std::string parentDir = filePath.substr(0, index); 1881 return parentDir == pkgToPath; 1882 } 1883 CheckImport(const std::string & importName)1884 bool Parser::CheckImport(const std::string &importName) 1885 { 1886 if (Options::GetInstance().GetInterfaceType() == InterfaceType::HDI) { 1887 if (!std::regex_match(importName.c_str(), RE_IMPORT)) { 1888 LogError(__func__, __LINE__, StringHelper::Format("invalid impirt name '%s'", importName.c_str())); 1889 return false; 1890 } 1891 } else { 1892 if (!std::regex_match(importName.c_str(), RE_PACKAGE_OR_IMPORT_SM)) { 1893 LogError(__func__, __LINE__, StringHelper::Format("invalid impirt name '%s'", importName.c_str())); 1894 return false; 1895 } 1896 } 1897 std::string idlFilePath = Options::GetInstance().GetImportFilePath(importName); 1898 if (!File::CheckValid(idlFilePath)) { 1899 LogError(__func__, __LINE__, StringHelper::Format("can not import '%s'", idlFilePath.c_str())); 1900 return false; 1901 } 1902 return true; 1903 } 1904 AddAst(const AutoPtr<AST> & ast)1905 bool Parser::AddAst(const AutoPtr<AST> &ast) 1906 { 1907 if (ast == nullptr) { 1908 LogError(__func__, __LINE__, std::string("ast is nullptr.")); 1909 return false; 1910 } 1911 1912 allAsts_[ast->GetFullName()] = ast; 1913 return true; 1914 } 1915 ShowError()1916 void Parser::ShowError() 1917 { 1918 for (const auto &errMsg : errors_) { 1919 Logger::E(TAG, "%s", errMsg.c_str()); 1920 } 1921 } 1922 ParseInterfaceExtends(AutoPtr<ASTInterfaceType> & interface)1923 void Parser::ParseInterfaceExtends(AutoPtr<ASTInterfaceType> &interface) 1924 { 1925 Token token = lexer_.PeekToken(); 1926 if (token.kind != TokenType::EXTENDS) { 1927 return; 1928 } 1929 lexer_.GetToken(); 1930 token = lexer_.PeekToken(); 1931 if (token.kind != TokenType::ID) { 1932 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected extends interface name")); 1933 lexer_.SkipToken(TokenType::BRACES_LEFT); 1934 return; 1935 } 1936 ParseExtendsInfo(interface); 1937 lexer_.GetToken(); 1938 } 1939 ParseExtendsInfo(AutoPtr<ASTInterfaceType> & interfaceType)1940 void Parser::ParseExtendsInfo(AutoPtr<ASTInterfaceType> &interfaceType) 1941 { 1942 Token token = lexer_.PeekToken(); 1943 std::string extendsInterfaceName = token.value; 1944 if (extendsInterfaceName.empty()) { 1945 LogError(__func__, __LINE__, token, std::string("extends interface name is empty")); 1946 return; 1947 } 1948 if (!CheckImport(extendsInterfaceName)) { 1949 LogError(__func__, __LINE__, token, std::string("extends interface name is illegal")); 1950 return; 1951 } 1952 auto iter = allAsts_.find(extendsInterfaceName); 1953 AutoPtr<AST> extendsAst = (iter != allAsts_.end()) ? iter->second : nullptr; 1954 if (extendsAst == nullptr) { 1955 LogError(__func__, __LINE__, token, StringHelper::Format("can not find idl file by extends interface " 1956 "name '%s', please check import info", extendsInterfaceName.c_str())); 1957 return; 1958 } 1959 if (!CheckExtendsName(interfaceType, extendsInterfaceName)) { 1960 LogError(__func__, __LINE__, token, StringHelper::Format( 1961 "extends interface name must same as current interface name '%s'", interfaceType->GetName().c_str())); 1962 return; 1963 } 1964 if (!CheckExtendsVersion(interfaceType, extendsInterfaceName, extendsAst)) { 1965 LogError(__func__, __LINE__, token, 1966 std::string("extends interface version must less than current interface version")); 1967 return; 1968 } 1969 if (!interfaceType->AddExtendsInterface(extendsAst->GetInterfaceDef())) { 1970 LogError(__func__, __LINE__, token, StringHelper::Format("multiple extends of '%s'", 1971 interfaceType->GetName().c_str())); 1972 } 1973 } 1974 CheckExtendsName(AutoPtr<ASTInterfaceType> & interfaceType,const std::string & extendsInterfaceName)1975 bool Parser::CheckExtendsName(AutoPtr<ASTInterfaceType> &interfaceType, const std::string &extendsInterfaceName) 1976 { 1977 size_t index = extendsInterfaceName.rfind("."); 1978 return (extendsInterfaceName.substr(index + 1).compare(interfaceType->GetName()) == 0) ? true : false; 1979 } 1980 CheckExtendsVersion(AutoPtr<ASTInterfaceType> & interfaceType,const std::string & extendsName,AutoPtr<AST> extendsAst)1981 bool Parser::CheckExtendsVersion( 1982 AutoPtr<ASTInterfaceType> &interfaceType, const std::string &extendsName, AutoPtr<AST> extendsAst) 1983 { 1984 if (extendsAst->GetMajorVer() != ast_->GetMajorVer() || extendsAst->GetMinorVer() >= ast_->GetMinorVer()) { 1985 return false; 1986 } 1987 return true; 1988 } 1989 CheckImportsVersion(AutoPtr<AST> extendsAst)1990 bool Parser::CheckImportsVersion(AutoPtr<AST> extendsAst) 1991 { 1992 if (extendsAst->GetMajorVer() != ast_->GetMajorVer() || extendsAst->GetMinorVer() > ast_->GetMinorVer()) { 1993 return false; 1994 } 1995 return true; 1996 } 1997 PostProcess()1998 bool Parser::PostProcess() 1999 { 2000 if ((Options::GetInstance().GetLanguage() != Language::C) || !CheckExistExtends()) { 2001 return true; 2002 } 2003 std::vector<size_t> genVersion = {0, 0}; 2004 std::string genPackageName; 2005 AutoPtr<ASTNamespace> ns; 2006 if (!GetGenVersion(genVersion, genPackageName)) { 2007 return false; 2008 } 2009 GetGenNamespace(ns); 2010 AstMergeMap mergeMap; 2011 SortAstByName(mergeMap, allAsts_); 2012 allAsts_.clear(); 2013 MergeAsts(mergeMap); 2014 ModifyImport(allAsts_, genPackageName); 2015 ModifyPackageNameAndVersion(allAsts_, genPackageName, genVersion); 2016 ModifyInterfaceNamespace(ns); 2017 2018 return true; 2019 } 2020 CheckExistExtends()2021 bool Parser::CheckExistExtends() 2022 { 2023 return std::any_of(allAsts_.begin(), allAsts_.end(), [](const std::pair<std::string, AutoPtr<AST>> &astPair) { 2024 return astPair.second->GetInterfaceDef() != nullptr && 2025 astPair.second->GetInterfaceDef()->GetExtendsInterface() != nullptr; 2026 }); 2027 } 2028 GetGenVersion(std::vector<size_t> & version,std::string & genPackageName)2029 bool Parser::GetGenVersion(std::vector<size_t> &version, std::string &genPackageName) 2030 { 2031 std::set<std::string> sourceFile = Options::GetInstance().GetSourceFiles(); 2032 for (const auto &ast : allAsts_) { 2033 if (sourceFile.find(ast.second->GetIdlFilePath()) != sourceFile.end()) { 2034 if (genPackageName.empty()) { 2035 genPackageName = ast.second->GetPackageName(); 2036 version[0] = ast.second->GetMajorVer(); 2037 version[1] = ast.second->GetMinorVer(); 2038 continue; 2039 } 2040 if (genPackageName != ast.second->GetPackageName() || version[0] != ast.second->GetMajorVer() || 2041 version[1] != ast.second->GetMinorVer()) { 2042 LogError(__func__, __LINE__, 2043 StringHelper::Format("merge ast failed, source files must have same package and version")); 2044 return false; 2045 } 2046 } 2047 } 2048 return true; 2049 } 2050 GetGenNamespace(AutoPtr<ASTNamespace> & ns)2051 void Parser::GetGenNamespace(AutoPtr<ASTNamespace> &ns) 2052 { 2053 std::set<std::string> sourceFile = Options::GetInstance().GetSourceFiles(); 2054 for (const auto &ast : allAsts_) { 2055 if ((sourceFile.find(ast.second->GetIdlFilePath()) != sourceFile.end()) && 2056 (ast.second->GetInterfaceDef() != nullptr)) { 2057 ns = ast.second->GetInterfaceDef()->GetNamespace(); 2058 return; 2059 } 2060 } 2061 } 2062 SortAstByName(AstMergeMap & mergeMap,StrAstMap & allAsts)2063 void Parser::SortAstByName(AstMergeMap &mergeMap, StrAstMap &allAsts) 2064 { 2065 for (const auto &astPair : allAsts) { 2066 AutoPtr<AST> ast = astPair.second; 2067 mergeMap[ast->GetName()].emplace(ast); 2068 } 2069 } 2070 MergeAsts(AstMergeMap & mergeMap)2071 void Parser::MergeAsts(AstMergeMap &mergeMap) 2072 { 2073 for (const auto &setPair : mergeMap) { 2074 AutoPtr<AST> targetAst = nullptr; 2075 for (const auto &ast : setPair.second) { 2076 MergeAst(targetAst, ast); 2077 } 2078 AddAst(targetAst); 2079 } 2080 } 2081 MergeAst(AutoPtr<AST> & targetAst,AutoPtr<AST> sourceAst)2082 void Parser::MergeAst(AutoPtr<AST> &targetAst, AutoPtr<AST> sourceAst) 2083 { 2084 if (targetAst == nullptr) { 2085 targetAst = sourceAst; 2086 return; 2087 } 2088 MergeImport(targetAst, sourceAst); 2089 MergeInterfaceDef(targetAst, sourceAst); 2090 MergeTypeDefinitions(targetAst, sourceAst); 2091 MergeTypes(targetAst, sourceAst); 2092 MergeSequenceableDef(targetAst, sourceAst); 2093 } 2094 MergeImport(AutoPtr<AST> & targetAst,AutoPtr<AST> sourceAst)2095 void Parser::MergeImport(AutoPtr<AST> &targetAst, AutoPtr<AST> sourceAst) 2096 { 2097 for (const auto &importPair : sourceAst->GetImports()) { 2098 AutoPtr<AST> importAst = importPair.second; 2099 targetAst->AddImport(importAst); 2100 } 2101 } 2102 MergeInterfaceDef(AutoPtr<AST> & targetAst,AutoPtr<AST> sourceAst)2103 void Parser::MergeInterfaceDef(AutoPtr<AST> &targetAst, AutoPtr<AST> sourceAst) 2104 { 2105 AutoPtr<ASTInterfaceType> sourceInterface = sourceAst->GetInterfaceDef(); 2106 if (sourceInterface == nullptr) { 2107 return; 2108 } 2109 AutoPtr<ASTInterfaceType> targetInterface = targetAst->GetInterfaceDef(); 2110 if (targetInterface == nullptr) { 2111 targetInterface = sourceInterface; 2112 return; 2113 } 2114 2115 for (size_t i = 0; i < sourceInterface->GetMethodNumber(); i++) { 2116 targetInterface->AddMethod(sourceInterface->GetMethod(i)); 2117 } 2118 targetInterface->SetSerializable(sourceInterface->IsSerializable()); 2119 } 2120 MergeTypeDefinitions(AutoPtr<AST> & targetAst,AutoPtr<AST> sourceAst)2121 void Parser::MergeTypeDefinitions(AutoPtr<AST> &targetAst, AutoPtr<AST> sourceAst) 2122 { 2123 for (size_t i = 0; i < sourceAst->GetTypeDefinitionNumber(); i++) { 2124 targetAst->AddTypeDefinition(sourceAst->GetTypeDefintion(i)); 2125 } 2126 } 2127 MergeSequenceableDef(AutoPtr<AST> & targetAst,AutoPtr<AST> sourceAst)2128 void Parser::MergeSequenceableDef(AutoPtr<AST> &targetAst, AutoPtr<AST> sourceAst) 2129 { 2130 if (sourceAst->GetSequenceableDef() != nullptr) { 2131 targetAst->AddSequenceableDef(sourceAst->GetSequenceableDef()); 2132 } 2133 } 2134 MergeTypes(AutoPtr<AST> & targetAst,AutoPtr<AST> sourceAst)2135 void Parser::MergeTypes(AutoPtr<AST> &targetAst, AutoPtr<AST> sourceAst) 2136 { 2137 for (const auto &typePair : sourceAst->GetTypes()) { 2138 targetAst->AddType(typePair.second); 2139 } 2140 } 2141 ModifyImport(StrAstMap & allAsts,std::string & genPackageName)2142 void Parser::ModifyImport(StrAstMap &allAsts, std::string &genPackageName) 2143 { 2144 for (const auto &astPair : allAsts) { 2145 StrAstMap modifiedImport; 2146 StrAstMap import = astPair.second->GetImports(); 2147 for (const auto &importPair : import) { 2148 if (importPair.second->GetName() == astPair.second->GetName()) { 2149 continue; 2150 } 2151 modifiedImport[importPair.second->GetName()] = importPair.second; 2152 } 2153 astPair.second->ClearImport(); 2154 for (const auto &importPair : modifiedImport) { 2155 importPair.second->SetPackageName(genPackageName); 2156 astPair.second->AddImport(importPair.second); 2157 } 2158 } 2159 } 2160 ModifyPackageNameAndVersion(StrAstMap & allAsts,std::string & genPackageName,std::vector<size_t> genVersion)2161 void Parser::ModifyPackageNameAndVersion( 2162 StrAstMap &allAsts, std::string &genPackageName, std::vector<size_t> genVersion) 2163 { 2164 for (const auto &astPair : allAsts) { 2165 astPair.second->SetPackageName(genPackageName); 2166 astPair.second->SetVersion(genVersion[0], genVersion[1]); 2167 } 2168 } 2169 ModifyInterfaceNamespace(AutoPtr<ASTNamespace> & ns)2170 void Parser::ModifyInterfaceNamespace(AutoPtr<ASTNamespace> &ns) 2171 { 2172 for (const auto &astPair : allAsts_) { 2173 AutoPtr<ASTInterfaceType> interface = astPair.second->GetInterfaceDef(); 2174 if (interface != nullptr) { 2175 interface->SetNamespace(ns); 2176 } 2177 } 2178 } 2179 } // namespace Idl 2180 } // namespace OHOS 2181