1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include "parser/parser.h"
10 #include <regex>
11 #include "ast/ast_array_type.h"
12 #include "ast/ast_enum_type.h"
13 #include "ast/ast_list_type.h"
14 #include "ast/ast_map_type.h"
15 #include "ast/ast_smq_type.h"
16 #include "ast/ast_parameter.h"
17 #include "ast/ast_sequenceable_type.h"
18 #include "ast/ast_struct_type.h"
19 #include "ast/ast_union_type.h"
20 #include "util/logger.h"
21 #include "util/string_builder.h"
22
23 #define RE_DIGIT "[0-9]+"
24 #define RE_IDENTIFIER "[a-zA-Z_][a-zA-Z0-9_]*"
25
26 #define RE_PACKAGE_NUM 3
27 #define RE_PACKAGE_INDEX 0
28 #define RE_PACKAGE_MAJOR_VER_INDEX 1
29 #define RE_PACKAGE_MINOR_VER_INDEX 2
30
31 namespace OHOS {
32 namespace HDI {
33 const char* Parser::TAG = "Parser";
34
35 static const std::regex rePackage(RE_IDENTIFIER "(?:\\." RE_IDENTIFIER ")*\\.[V|v]" "(" RE_DIGIT ")_(" RE_DIGIT ")");
36 static const std::regex reImport(RE_IDENTIFIER "(?:\\." RE_IDENTIFIER ")*\\.[V|v]" \
37 RE_DIGIT "_" RE_DIGIT "." RE_IDENTIFIER);
38
Parser(const Options & options,const AutoPtr<ASTModule> & module)39 Parser::Parser(const Options& options, const AutoPtr<ASTModule>& module)
40 :options_(options), lexer_(nullptr), errors_(nullptr), ast_(nullptr), astModule_(module)
41 {}
42
Parse(const String & sourceFile)43 bool Parser::Parse(const String& sourceFile)
44 {
45 lexer_ = std::make_shared<Lexer>();
46 bool ret = lexer_->OpenSourceFile(sourceFile);
47 if (!ret) {
48 Logger::E(TAG, "Fail to open file '%s'.", sourceFile.string());
49 return false;
50 }
51
52 ret = ParseFile();
53 ret = CheckIntegrity() && ret;
54 ret = AddAst() && ret;
55 if (!ret || errors_ != nullptr) {
56 ShowError();
57 return false;
58 }
59
60 if (options_.DoDumpAST()) {
61 String astStr = ast_->Dump("");
62 printf("%s\n", astStr.string());
63 }
64
65 return ret;
66 }
67
Parse(const String & sourceFile,std::shared_ptr<FileDetail> & fileDetailPtr)68 bool Parser::Parse(const String& sourceFile, std::shared_ptr<FileDetail>& fileDetailPtr)
69 {
70 lexer_ = std::make_shared<Lexer>();
71 bool ret = lexer_->OpenSourceFile(sourceFile);
72 if (!ret) {
73 Logger::E(TAG, "Fail to open file '%s'.", sourceFile.string());
74 return false;
75 }
76
77 ret = ParseIdlDetail(fileDetailPtr);
78 if (!ret) {
79 ShowError();
80 return false;
81 }
82
83 return ret;
84 }
85
ParseIdlDetail(std::shared_ptr<FileDetail> & fileDetailPtr)86 bool Parser::ParseIdlDetail(std::shared_ptr<FileDetail>& fileDetailPtr)
87 {
88 bool ret = true;
89 fileDetailPtr = std::make_shared<FileDetail>();
90 fileDetailPtr->SetFilePath(lexer_->GetFilePath());
91
92 Token token;
93 while ((token = lexer_->PeekToken()) != Token::END_OF_FILE) {
94 switch (token) {
95 case Token::PACKAGE:
96 ret = ParseIdlPackage(fileDetailPtr) && ret;
97 break;
98 case Token::IMPORT:
99 ret = ParseIdlImport(fileDetailPtr) && ret;
100 break;
101 default:
102 lexer_->GetToken();
103 break;
104 }
105 }
106 lexer_->GetToken();
107 return ret;
108 }
109
ParseIdlPackage(std::shared_ptr<FileDetail> & fileDetailPtr)110 bool Parser::ParseIdlPackage(std::shared_ptr<FileDetail>& fileDetailPtr)
111 {
112 lexer_->GetToken();
113 String packageName;
114
115 Token token = lexer_->PeekToken();
116 if (token != Token::IDENTIFIER) {
117 if (token == Token::SEMICOLON) {
118 LogError(String::Format("expected identifier before ';'."));
119 lexer_->GetToken();
120 } else {
121 LogError(String::Format("'%s' is an invalid package name.", lexer_->DumpToken().string()));
122 }
123 lexer_->SkipCurrentLine();
124 return false;
125 } else {
126 lexer_->GetToken();
127 packageName = lexer_->GetIdentifier();
128 token = lexer_->PeekToken();
129 }
130
131 if (token != Token::SEMICOLON) {
132 LogError(String::Format("expected ';' before '%s'", lexer_->DumpToken().string()));
133 return false;
134 }
135
136 // read ';'
137 lexer_->GetToken();
138
139 if (packageName.IsEmpty()) {
140 LogError(String("Package name is not expected."));
141 return false;
142 } else if (!IsValidTypeName(packageName)) {
143 LogError(String::Format("Package name '%s' is illegal.", packageName.string()));
144 return false;
145 } else if (!CheckPackageName(lexer_->GetFilePath(), packageName)) {
146 LogError(String::Format("Package name '%s' does not match file apth '%s'.",
147 packageName.string(), lexer_->GetFilePath().string()));
148 return false;
149 }
150
151 fileDetailPtr->SetPackageName(packageName);
152
153 return true;
154 }
155
ParseIdlImport(std::shared_ptr<FileDetail> & fileDetailPtr)156 bool Parser::ParseIdlImport(std::shared_ptr<FileDetail>& fileDetailPtr)
157 {
158 lexer_->GetToken();
159
160 String importPkgName;
161 Token token = lexer_->PeekToken();
162 if (token != Token::IDENTIFIER) {
163 if (token == Token::SEMICOLON) {
164 LogError(String::Format("expected identifier before ';'."));
165 lexer_->GetToken();
166 } else {
167 LogError(String::Format("'%s' is an invalid import package name.", lexer_->DumpToken().string()));
168 }
169 lexer_->SkipCurrentLine();
170 return false;
171 }
172 lexer_->GetToken();
173 importPkgName = lexer_->GetIdentifier();
174
175 token = lexer_->PeekToken();
176 if (token != Token::SEMICOLON) {
177 LogError(String::Format("expected ';' before '%s'.", lexer_->DumpToken().string()));
178 return false;
179 }
180
181 // read ';'
182 lexer_->GetToken();
183 if (importPkgName.IsEmpty()) {
184 LogError(String("import package name is not expected."));
185 return false;
186 } else if (!IsValidTypeName(importPkgName)) {
187 LogError(String::Format("import package name '%s' is illegal.", importPkgName.string()));
188 return false;
189 }
190
191 if (!fileDetailPtr->AddImport(importPkgName)) {
192 LogError(String::Format("the package of '%s' has been imported.", importPkgName.string()));
193 return false;
194 }
195
196 return true;
197 }
198
ParseFile()199 bool Parser::ParseFile()
200 {
201 bool ret = true;
202 ast_ = new AST();
203 ast_->SetIdlFile(lexer_->GetFilePath());
204 ParseLicense();
205
206 Token token;
207 while ((token = lexer_->PeekToken()) != Token::END_OF_FILE) {
208 switch (token) {
209 case Token::PACKAGE:
210 ret = ParsePackageName() && ret;
211 continue;
212 case Token::IMPORT:
213 ret = ParseImport() && ret;
214 continue;
215 case Token::SEQUENCEABLE:
216 ret = ParseSequenceable() && ret;
217 continue;
218 case Token::BRACKETS_LEFT:
219 ret = ParseAttribute() && ret;
220 continue;
221 case Token::INTERFACE:
222 ret = ParseInterface() && ret;
223 continue;
224 case Token::COMMENT_LINE:
225 lexer_->GetToken();
226 continue;
227 case Token::ENUM:
228 ret = ParseEnumDefine() && ret;
229 continue;
230 case Token::STRUCT:
231 ret = ParseStructDefine() && ret;
232 continue;
233 case Token::UNION:
234 ret = ParseUnionDefine() && ret;
235 continue;
236 default:
237 LogError(String::Format("'%s' is not expected.", lexer_->DumpToken().string()));
238 lexer_->GetToken();
239 ret = false;
240 continue;
241 }
242 }
243 lexer_->GetToken();
244 SetAstFileType();
245
246 return ret;
247 }
248
ParseLicense()249 bool Parser::ParseLicense()
250 {
251 Token token = lexer_->PeekToken(false);
252 if (token != Token::COMMENT_BLOCK) {
253 return false;
254 }
255
256 lexer_->GetToken(false);
257
258 ast_->SetLicense(lexer_->GetComment());
259
260 return true;
261 }
262
ParsePackageName()263 bool Parser::ParsePackageName()
264 {
265 lexer_->GetToken();
266 String packageFullName;
267 Token token = lexer_->PeekToken();
268 if (token != Token::IDENTIFIER) {
269 if (token == Token::SEMICOLON) {
270 LogError(String::Format("expected identifier before ';'."));
271 } else {
272 LogError(String::Format("'%s' is an invalid package name.", lexer_->DumpToken().string()));
273 }
274 lexer_->SkipCurrentLine();
275 lexer_->GetToken();
276 return false;
277 } else {
278 lexer_->GetToken();
279 packageFullName = lexer_->GetIdentifier();
280 token = lexer_->PeekToken();
281 }
282
283 if (token != Token::SEMICOLON) {
284 LogError(String::Format("expected ';' before '%s'", lexer_->DumpToken().string()));
285 return false;
286 }
287
288 // read ';'
289 lexer_->GetToken();
290 if (packageFullName.IsEmpty()) {
291 LogError(String("Package name is not expected."));
292 return false;
293 } else if (!IsValidTypeName(packageFullName)) {
294 LogError(String::Format("Package name '%s' is illegal.", packageFullName.string()));
295 return false;
296 } else if (!CheckPackageName(lexer_->GetFilePath(), packageFullName)) {
297 LogError(String::Format("Package name '%s' does not match file apth '%s'.",
298 packageFullName.string(), lexer_->GetFilePath().string()));
299 return false;
300 }
301
302 if (!ParserPackageInfo(packageFullName)) {
303 LogError(String::Format("Parse package '%s' infomation failed.", packageFullName.string()));
304 return false;
305 }
306
307 return true;
308 }
309
ParserPackageInfo(const String & packageName)310 bool Parser::ParserPackageInfo(const String& packageName)
311 {
312 std::cmatch result;
313 if (!std::regex_match(packageName.string(), result, rePackage)) {
314 return false;
315 }
316
317 if (result.size() < RE_PACKAGE_NUM) {
318 return false;
319 }
320
321 ast_->SetPackageName(result.str(RE_PACKAGE_INDEX).c_str());
322 size_t majorVersion = std::atoi(result.str(RE_PACKAGE_MAJOR_VER_INDEX).c_str());
323 size_t minorVersion = std::atoi(result.str(RE_PACKAGE_MINOR_VER_INDEX).c_str());
324 ast_->SetVersion(majorVersion, minorVersion);
325 return true;
326 }
327
ParseImport()328 bool Parser::ParseImport()
329 {
330 lexer_->GetToken();
331 String packageFullName;
332 Token token = lexer_->PeekToken();
333 if (token != Token::IDENTIFIER) {
334 if (token == Token::SEMICOLON) {
335 LogError(String::Format("expected identifier before ';'."));
336 } else {
337 LogError(String::Format("%s is an invalid import package name.", lexer_->DumpToken().string()));
338 }
339 lexer_->SkipCurrentLine();
340 lexer_->GetToken();
341 return false;
342 }
343 lexer_->GetToken();
344 packageFullName = lexer_->GetIdentifier();
345
346 token = lexer_->PeekToken();
347 if (token != Token::SEMICOLON) {
348 LogError(String::Format("expected ';' before '%s'.", lexer_->DumpToken().string()));
349 return false;
350 }
351
352 // read ';'
353 lexer_->GetToken();
354 if (packageFullName.IsEmpty()) {
355 LogError(String("import package name is not expected."));
356 return false;
357 } else if (!IsValidTypeName(packageFullName)) {
358 LogError(String::Format("import package name '%s' is illegal.", packageFullName.string()));
359 return false;
360 }
361
362 AutoPtr<AST> importAst = astModule_->GetAst(packageFullName);
363 if (importAst == nullptr) {
364 LogError(String("not find import ast."));
365 return false;
366 }
367
368 AutoPtr<ASTInterfaceType> interfaceType = importAst->GetInterfaceDef();
369 if (interfaceType != nullptr) {
370 interfaceType->SetSerializable(true);
371 }
372
373 if (!ast_->AddImport(importAst)) {
374 LogError(String::Format("the package '%s' has been import", packageFullName.string()));
375 return false;
376 }
377 return true;
378 }
379
ParseSequenceable()380 bool Parser::ParseSequenceable()
381 {
382 lexer_->GetToken();
383 String classFullName;
384
385 Token token = lexer_->PeekToken();
386 if (token != Token::IDENTIFIER) {
387 if (token == Token::SEMICOLON) {
388 LogError(String::Format("expected identifier before ';'."));
389 } else {
390 LogError(String::Format("'%s' is not expected.", lexer_->DumpToken().string()));
391 }
392 lexer_->SkipCurrentLine();
393 lexer_->GetToken();
394 return false;
395 }
396 lexer_->GetToken();
397 classFullName = lexer_->GetIdentifier();
398
399 token = lexer_->PeekToken();
400 if (token != Token::SEMICOLON) {
401 LogError(String::Format("expected ';' before '%s'.", lexer_->DumpToken().string()));
402 return false;
403 }
404 // read ';'
405 lexer_->GetToken();
406
407 if (classFullName.IsEmpty()) {
408 LogError(String("class name is not expected."));
409 return false;
410 } else if (!IsValidTypeName(classFullName)) {
411 LogError(String::Format("class name '%s' is illegal.", classFullName.string()));
412 return false;
413 }
414
415 AutoPtr<ASTSequenceableType> sequenceable = new ASTSequenceableType();
416 int index = classFullName.LastIndexOf('.');
417 if (index != -1) {
418 sequenceable->SetName(classFullName.Substring(index + 1));
419 sequenceable->SetNamespace(ast_->ParseNamespace(classFullName.Substring(0, index + 1)));
420 } else {
421 sequenceable->SetName(classFullName);
422 }
423
424 AutoPtr<AST> sequenceableAst = new AST();
425 sequenceableAst->SetFullName(classFullName);
426 sequenceableAst->AddSequenceableDef(sequenceable);
427 sequenceableAst->SetAStFileType(ASTFileType::AST_SEQUENCEABLE);
428 ast_->AddImport(sequenceableAst);
429
430 return true;
431 }
432
ParseAttribute()433 bool Parser::ParseAttribute()
434 {
435 bool ret = true;
436 AutoPtr<Attribute> attributes = nullptr;
437
438 if (!ParseAttributeBody(attributes)) {
439 return false;
440 }
441
442 Token token = lexer_->PeekToken();
443 switch (token) {
444 case Token::ENUM:
445 ret = ParseEnumDefine(attributes) && ret;
446 break;
447 case Token::STRUCT:
448 ret = ParseStructDefine(attributes) && ret;
449 break;
450 case Token::UNION:
451 ret = ParseUnionDefine(attributes) && ret;
452 break;
453 case Token::INTERFACE:
454 ret = ParseInterface(attributes) && ret;
455 break;
456 default: {
457 LogError(String::Format("'%s' is not expected.", lexer_->DumpToken().string()));
458 return false;
459 }
460 }
461 return ret;
462 }
463
ParseInterface(const AutoPtr<Attribute> & attributes)464 bool Parser::ParseInterface(const AutoPtr<Attribute>& attributes)
465 {
466 lexer_->GetToken();
467 String interfaceName;
468
469 Token token = lexer_->PeekToken();
470 if (token != Token::IDENTIFIER) {
471 LogError(String::Format("'%s' is not expected.", lexer_->DumpToken().string()));
472 lexer_->Skip('}');
473 lexer_->GetToken();
474 return false;
475 }
476 lexer_->GetToken();
477 interfaceName = lexer_->GetIdentifier();
478
479 token = lexer_->PeekToken();
480 if (token != Token::BRACES_LEFT) {
481 LogError(String::Format("expected '{' after the '%s'.", lexer_->DumpToken().string()));
482 lexer_->Skip('}');
483 lexer_->GetToken();
484 return false;
485 }
486 lexer_->GetToken();
487
488 if (interfaceName.IsEmpty()) {
489 LogError(String("interface name is expected."));
490 return false;
491 }
492
493 AutoPtr<ASTInterfaceType> interface = new ASTInterfaceType();
494 interface->SetName(interfaceName);
495 interface->SetNamespace(ast_->ParseNamespace(ast_->GetFullName()));
496
497 if (!interface->GetName().Equals(ast_->GetName())) {
498 LogError(String::Format("Module name '%s' is not equal to interface name '%s'.",
499 ast_->GetName().string(), interface->GetName().string()));
500 }
501
502 interface->SetLicense(ast_->GetLicense());
503 if (attributes != nullptr) {
504 interface->SetOneWay(attributes->isOneWay);
505 interface->SetCallback(attributes->isCallback);
506 interface->SetFull(attributes->isFull);
507 interface->SetLite(attributes->isLite);
508 }
509 return ParseInterfaceBody(interface);
510 }
511
ParseInterfaceBody(const AutoPtr<ASTInterfaceType> & interface)512 bool Parser::ParseInterfaceBody(const AutoPtr<ASTInterfaceType>& interface)
513 {
514 bool ret = true;
515 Token token = lexer_->PeekToken();
516 while (token != Token::BRACES_RIGHT && token != Token::END_OF_FILE) {
517 ret = ParseMethod(interface) && ret;
518 token = lexer_->PeekToken();
519 }
520
521 if (token != Token::BRACES_RIGHT) {
522 LogError(String::Format("'%s' is not expected.", lexer_->DumpToken().string()));
523 lexer_->SkipEof();
524 return false;
525 }
526 lexer_->GetToken();
527
528 token = lexer_->PeekToken();
529 if (token == Token::SEMICOLON) {
530 lexer_->GetToken();
531 }
532
533 if (ast_->GetInterfaceDef() != nullptr) {
534 LogError(String::Format("an interface class already exists int idl file."));
535 lexer_->SkipEof();
536 return false;
537 }
538
539 SetVersionInterfaceMethod(interface);
540
541 ast_->AddInterfaceDef(interface);
542 return ret;
543 }
544
ParseMethod(const AutoPtr<ASTInterfaceType> & interface)545 bool Parser::ParseMethod(const AutoPtr<ASTInterfaceType>& interface)
546 {
547 AutoPtr<Attribute> attributes = nullptr;
548 if (!ParseAttributeBody(attributes)) {
549 return false;
550 }
551
552 Token token = lexer_->PeekToken();
553 if (token != Token::IDENTIFIER) {
554 LogError(String("Method name is expected."));
555 if (token == Token::BRACES_RIGHT) {
556 return false;
557 }
558 // jump over colon
559 lexer_->GetToken();
560 while (token != Token::SEMICOLON && token != Token::END_OF_FILE) {
561 token = lexer_->PeekToken();
562 if (token == Token::BRACES_RIGHT) {
563 break;
564 }
565 lexer_->GetToken();
566 }
567 return false;
568 }
569 lexer_->GetToken();
570
571 AutoPtr<ASTMethod> method = new ASTMethod();
572 method->SetName(lexer_->GetIdentifier());
573
574 if (attributes != nullptr) {
575 method->SetOneWay(attributes->isOneWay || interface->IsOneWay());
576 method->SetFull(attributes->isFull);
577 method->SetLite(attributes->isLite);
578 }
579
580 if (!ParseParameterList(method)) {
581 return false;
582 }
583
584 interface->AddMethod(method);
585 return true;
586 }
587
SetVersionInterfaceMethod(const AutoPtr<ASTInterfaceType> & interface)588 void Parser::SetVersionInterfaceMethod(const AutoPtr<ASTInterfaceType>& interface)
589 {
590 AutoPtr<ASTMethod> method = new ASTMethod();
591 method->SetName("GetVersion");
592
593 AutoPtr<ASTType> type = ast_->FindType("unsigned int");
594 if (type == nullptr) {
595 type = new ASTUintType();
596 }
597 AutoPtr<ASTParameter> majorParam = new ASTParameter("majorVer", ParamAttr::PARAM_OUT, type);
598 AutoPtr<ASTParameter> minorParam = new ASTParameter("minorVer", ParamAttr::PARAM_OUT, type);
599
600 method->AddParameter(majorParam);
601 method->AddParameter(minorParam);
602 interface->AddVersionMethod(method);
603 }
604
ParseAttributeBody(AutoPtr<Attribute> & attributes)605 bool Parser::ParseAttributeBody(AutoPtr<Attribute>& attributes)
606 {
607 Token token = lexer_->PeekToken();
608 if (token != Token::BRACKETS_LEFT) {
609 return true;
610 }
611 lexer_->GetToken();
612 attributes = new Attribute();
613 token = lexer_->PeekToken();
614 while (token != Token::BRACKETS_RIGHT) {
615 if (!ParseAttributeParam(attributes)) {
616 return false;
617 }
618
619 token = lexer_->PeekToken();
620 if (token == Token::COMMA) {
621 lexer_->GetToken();
622 token = lexer_->PeekToken();
623 } else if (token == Token::BRACKETS_RIGHT) {
624 break;
625 } else {
626 LogError(String::Format("'%s' is not expected.", lexer_->DumpToken().string()));
627 lexer_->Skip(Lexer::TokenToChar(Token::BRACKETS_RIGHT));
628 lexer_->GetToken();
629 return false;
630 }
631 }
632 lexer_->GetToken();
633 return true;
634 }
635
ParseAttributeParam(AutoPtr<Attribute> & attributes)636 bool Parser::ParseAttributeParam(AutoPtr<Attribute>& attributes)
637 {
638 Token token = lexer_->GetToken();
639 switch (token) {
640 case Token::ONEWAY:
641 if (options_.DoGenerateKernelCode()) {
642 LogError(String::Format("'%s' is not supported in kernel code.", lexer_->DumpToken().string()));
643 lexer_->Skip(Lexer::TokenToChar(Token::BRACKETS_RIGHT));
644 lexer_->GetToken();
645 return false;
646 }
647 attributes->isOneWay = true;
648 break;
649 case Token::CALLBACK:
650 attributes->isCallback = true;
651 break;
652 case Token::FULL:
653 attributes->isFull = true;
654 break;
655 case Token::LITE:
656 attributes->isLite = true;
657 break;
658 default: {
659 LogError(String::Format("'%s' is not expected.", lexer_->DumpToken().string()));
660 lexer_->Skip(Lexer::TokenToChar(Token::BRACKETS_RIGHT));
661 lexer_->GetToken();
662 return false;
663 }
664 }
665 return true;
666 }
667
ParseParameterList(AutoPtr<ASTMethod> & method)668 bool Parser::ParseParameterList(AutoPtr<ASTMethod>& method)
669 {
670 bool ret = true;
671 Token token = lexer_->PeekToken();
672 if (token != Token::PARENTHESES_LEFT) {
673 LogError(String("'(' is expected."));
674 lexer_->Skip(';');
675 return false;
676 }
677 lexer_->GetToken();
678
679 token = lexer_->PeekToken();
680 while (token != Token::PARENTHESES_RIGHT && token != Token::END_OF_FILE) {
681 ret = ParseParameter(method) && ret;
682 token = lexer_->PeekToken();
683 if (token == Token::COMMA) {
684 lexer_->GetToken();
685 token = lexer_->PeekToken();
686 } else if (token != Token::PARENTHESES_RIGHT) {
687 LogError(String::Format("'%s' is not expected.", lexer_->DumpToken().string()));
688 lexer_->SkipCurrentLine(';');
689 lexer_->GetToken();
690 return false;
691 }
692 }
693
694 lexer_->GetToken();
695 if (!ret) {
696 lexer_->SkipCurrentLine();
697 return false;
698 }
699
700 token = lexer_->PeekToken();
701 if (token != Token::SEMICOLON) {
702 LogError(String("';' is expected."));
703 return false;
704 }
705 lexer_->GetToken();
706 return true;
707 }
708
ParseParameter(const AutoPtr<ASTMethod> & method)709 bool Parser::ParseParameter(const AutoPtr<ASTMethod>& method)
710 {
711 AutoPtr<ASTParameter> parameter = new ASTParameter();
712 if (!ParseParamAttr(parameter)) {
713 return false;
714 }
715
716 AutoPtr<ASTType> type = ParseType();
717
718 Token token = lexer_->PeekToken();
719 if (type == nullptr) {
720 while (token != Token::COMMA && token != Token::PARENTHESES_RIGHT && token != Token::END_OF_FILE) {
721 lexer_->GetToken();
722 token = lexer_->PeekToken();
723 }
724 return false;
725 }
726
727 if (token != Token::IDENTIFIER) {
728 LogError(String("Parameter name is expected."));
729 while (token != Token::COMMA && token != Token::PARENTHESES_RIGHT && token != Token::END_OF_FILE) {
730 lexer_->GetToken();
731 token = lexer_->PeekToken();
732 }
733 return false;
734 }
735 lexer_->GetToken();
736
737 if (type->IsInterfaceType()) {
738 AutoPtr<ASTInterfaceType> interfaceType = dynamic_cast<ASTInterfaceType*>(type.Get());
739 if (interfaceType->IsCallback() && parameter->GetAttribute() != ParamAttr::PARAM_IN) {
740 LogError(String::Format("The attribute of callback interface parameter '%s' does not be 'in'",
741 lexer_->GetIdentifier().string()));
742 return false;
743 }
744
745 if (!interfaceType->IsCallback() && parameter->GetAttribute() != ParamAttr::PARAM_OUT) {
746 LogError(String::Format("The attribute of interface parameter '%s' does not be 'in'",
747 lexer_->GetIdentifier().string()));
748 return false;
749 }
750 }
751
752 parameter->SetName(lexer_->GetIdentifier());
753 parameter->SetType(type);
754
755 if (method->IsOneWay() && parameter->GetAttribute() == ParamAttr::PARAM_OUT) {
756 LogError(String::Format("The attribute of parameter '%s' cannot be 'out'.", parameter->GetName().string()));
757 return false;
758 }
759
760 method->AddParameter(parameter);
761 return true;
762 }
763
ParseParamAttr(const AutoPtr<ASTParameter> & parameter)764 bool Parser::ParseParamAttr(const AutoPtr<ASTParameter>& parameter)
765 {
766 Token token = lexer_->PeekToken();
767 if (token != Token::BRACKETS_LEFT) {
768 LogError(String("'[' is expected."));
769 while (token != Token::COMMA && token != Token::PARENTHESES_RIGHT && token != Token::END_OF_FILE) {
770 lexer_->GetToken();
771 token = lexer_->PeekToken();
772 }
773 return false;
774 }
775 lexer_->GetToken();
776
777 if (parameter == nullptr) {
778 return false;
779 }
780
781 token = lexer_->PeekToken();
782 if (token == Token::IN) {
783 lexer_->GetToken();
784 parameter->SetAttribute(ParamAttr::PARAM_IN);
785 } else if (token == Token::OUT) {
786 lexer_->GetToken();
787 parameter->SetAttribute(ParamAttr::PARAM_OUT);
788 } else {
789 LogError(String::Format("'%s' is not a parameter property, it must be 'in' or 'out'.",
790 lexer_->DumpToken().string()));
791 while (token != Token::SEMICOLON && token != Token::END_OF_FILE) {
792 lexer_->GetToken();
793 token = lexer_->PeekToken();
794 }
795 return false;
796 }
797
798 token = lexer_->PeekToken();
799 if (token != Token::BRACKETS_RIGHT) {
800 LogError(String::Format("']' is expected."));
801 while (token != Token::SEMICOLON && token != Token::END_OF_FILE) {
802 lexer_->GetToken();
803 token = lexer_->PeekToken();
804 }
805 return false;
806 }
807 lexer_->GetToken();
808
809 return true;
810 }
811
ParseType()812 AutoPtr<ASTType> Parser::ParseType()
813 {
814 int typeLineNo = lexer_->GetTokenLineNumber();
815 int typeColumnNo = lexer_->GetTokenColumnNumber();
816 AutoPtr<ASTType> type;
817
818 Token token = lexer_->PeekToken();
819 if (IsPrimitiveType(token)) {
820 lexer_->GetToken();
821 type = ast_->FindType(lexer_->DumpToken());
822 } else if (token == Token::LIST) {
823 type = ParseList();
824 } else if (token == Token::MAP) {
825 type = ParseMap();
826 } else if (token == Token::SMEMQUEUE) {
827 type = ParseSharedMemQueueMetaType();
828 } else if (token == Token::ENUM || token == Token::STRUCT || token == Token::UNION) {
829 type = ParseCustomType();
830 } else if (token == Token::IDENTIFIER) {
831 lexer_->GetToken();
832 type = ast_->FindType(lexer_->GetIdentifier());
833 } else if (token == Token::UNSIGNED) {
834 lexer_->GetToken();
835 type = ParseUnsignedType(typeLineNo, typeColumnNo);
836 } else {
837 LogError(typeLineNo, typeColumnNo, String("Invalid type name."));
838 return nullptr;
839 }
840
841 if (type == nullptr) {
842 LogError(typeLineNo, typeColumnNo, String::Format("Type '%s' was not declared in any idl file.",
843 lexer_->DumpToken().string()));
844 }
845
846 token = lexer_->PeekToken();
847 if (token == Token::BRACKETS_LEFT) {
848 lexer_->GetToken();
849 type = ParseArrayType(type);
850 }
851
852 if (!CheckType(typeLineNo, typeColumnNo, type)) {
853 return nullptr;
854 }
855
856 return type;
857 }
858
ParseUnsignedType(int typeLineNo,int typeColumnNo)859 AutoPtr<ASTType> Parser::ParseUnsignedType(int typeLineNo, int typeColumnNo)
860 {
861 AutoPtr<ASTType> type = nullptr;
862 String unsignedStr = lexer_->DumpToken();
863 Token token = lexer_->PeekToken();
864 switch (token) {
865 case Token::CHAR:
866 case Token::SHORT:
867 case Token::INTEGER:
868 case Token::LONG: {
869 type = ast_->FindType(unsignedStr + " " + lexer_->DumpToken());
870 lexer_->GetToken();
871 break;
872 }
873 default: {
874 LogError(typeLineNo, typeColumnNo,
875 String::Format("'unsigned %s' type was not declared in the idl file.",
876 lexer_->DumpToken().string()));
877 return nullptr;
878 }
879 }
880
881 return type;
882 }
883
ParseList()884 AutoPtr<ASTType> Parser::ParseList()
885 {
886 lexer_->GetToken();
887
888 Token token = lexer_->PeekToken();
889 if (token != Token::ANGLE_BRACKETS_LEFT) {
890 LogError(String("'<' is expected."));
891 return nullptr;
892 }
893 lexer_->GetToken();
894
895 AutoPtr<ASTType> type = ParseType();
896 if (type == nullptr) {
897 lexer_->SkipCurrentLine('>');
898 lexer_->GetToken();
899 return nullptr;
900 }
901
902 token = lexer_->PeekToken();
903 if (token != Token::ANGLE_BRACKETS_RIGHT) {
904 LogError(String("'>' is expected."));
905 return nullptr;
906 }
907 lexer_->GetToken();
908
909 AutoPtr<ASTListType> list = new ASTListType();
910 list->SetElementType(type);
911
912 AutoPtr<ASTType> ret = ast_->FindType(list->ToString());
913 if (ret == nullptr) {
914 ast_->AddType(list.Get());
915 ret = list.Get();
916 }
917
918 return ret;
919 }
920
ParseMap()921 AutoPtr<ASTType> Parser::ParseMap()
922 {
923 lexer_->GetToken();
924
925 Token token = lexer_->PeekToken();
926 if (token != Token::ANGLE_BRACKETS_LEFT) {
927 LogError(String("'<' is expected."));
928 return nullptr;
929 }
930 lexer_->GetToken();
931
932 AutoPtr<ASTType> keyType = ParseType();
933 if (keyType == nullptr) {
934 lexer_->SkipCurrentLine('>');
935 return nullptr;
936 }
937
938 token = lexer_->PeekToken();
939 if (token != Token::COMMA) {
940 LogError(String("',' is expected."));
941 return nullptr;
942 }
943 lexer_->GetToken();
944
945 AutoPtr<ASTType> valueType = ParseType();
946 if (valueType == nullptr) {
947 lexer_->SkipCurrentLine('>');
948 return nullptr;
949 }
950
951 token = lexer_->PeekToken();
952 if (token != Token::ANGLE_BRACKETS_RIGHT) {
953 LogError(String("'>' is expected."));
954 return nullptr;
955 }
956 lexer_->GetToken();
957
958 AutoPtr<ASTMapType> map = new ASTMapType();
959 map->SetKeyType(keyType);
960 map->SetValueType(valueType);
961
962 AutoPtr<ASTType> ret = ast_->FindType(map->ToString());
963 if (ret == nullptr) {
964 ast_->AddType(map.Get());
965 ret = map.Get();
966 }
967
968 return ret;
969 }
970
ParseSharedMemQueueMetaType()971 AutoPtr<ASTType> Parser::ParseSharedMemQueueMetaType()
972 {
973 lexer_->GetToken();
974
975 Token token = lexer_->PeekToken();
976 if (token != Token::ANGLE_BRACKETS_LEFT) {
977 LogError(String("'<' is expected."));
978 return nullptr;
979 }
980 lexer_->GetToken();
981
982 AutoPtr<ASTType> InnerType = ParseType();
983 if (InnerType == nullptr) {
984 lexer_->SkipCurrentLine('>');
985 return nullptr;
986 }
987
988 token = lexer_->PeekToken();
989 if (token != Token::ANGLE_BRACKETS_RIGHT) {
990 LogError(String("'>' is expected."));
991 return nullptr;
992 }
993 lexer_->GetToken();
994
995 AutoPtr<ASTSmqType> type = new ASTSmqType();
996 type->SetInnerType(InnerType);
997 AutoPtr<ASTType> ret = ast_->FindType(type->ToString());
998 if (ret == nullptr) {
999 ast_->AddType(type.Get());
1000 ret = type.Get();
1001 }
1002
1003 return ret;
1004 }
1005
ParseArrayType(const AutoPtr<ASTType> & elementType)1006 AutoPtr<ASTType> Parser::ParseArrayType(const AutoPtr<ASTType>& elementType)
1007 {
1008 Token token = lexer_->PeekToken();
1009 if (token != Token::BRACKETS_RIGHT) {
1010 LogError(String("']' is expected."));
1011 return nullptr;
1012 }
1013 lexer_->GetToken();
1014
1015 if (elementType == nullptr) {
1016 return nullptr;
1017 }
1018
1019 AutoPtr<ASTArrayType> arrayType = new ASTArrayType();
1020 arrayType->SetElementType(elementType);
1021 AutoPtr<ASTType> type = ast_->FindType(arrayType->ToString());
1022
1023 if (type == nullptr) {
1024 ast_->AddType(arrayType.Get());
1025 type = static_cast<ASTType*>(arrayType.Get());
1026 }
1027
1028 return type;
1029 }
1030
ParseCustomType()1031 AutoPtr<ASTType> Parser::ParseCustomType()
1032 {
1033 Token token = lexer_->GetToken();
1034 String typePrefix;
1035 if (token == Token::ENUM) {
1036 typePrefix = "enum";
1037 } else if (token == Token::STRUCT) {
1038 typePrefix = "struct";
1039 } else if (token == Token::UNION) {
1040 typePrefix = "union";
1041 }
1042
1043 token = lexer_->PeekToken();
1044 if (token != Token::IDENTIFIER) {
1045 LogError(String("custom type name is expected."));
1046 return nullptr;
1047 }
1048
1049 String typeName = typePrefix + " " + lexer_->GetIdentifier();
1050 lexer_->GetToken();
1051 AutoPtr<ASTType> type = ast_->FindType(typeName);
1052 if (type != nullptr) {
1053 ast_->AddType(type);
1054 }
1055
1056 return type;
1057 }
1058
ParseEnumDefine(const AutoPtr<Attribute> & attributes)1059 bool Parser::ParseEnumDefine(const AutoPtr<Attribute>& attributes)
1060 {
1061 lexer_->GetToken();
1062 AutoPtr<ASTEnumType> type = new ASTEnumType();
1063
1064 Token token = lexer_->PeekToken();
1065 if (token != Token::IDENTIFIER) {
1066 LogError(String("custom enum type name is expected."));
1067 return false;
1068 }
1069 type->SetName(lexer_->GetIdentifier());
1070 lexer_->GetToken();
1071
1072 if (!ParseEnumBaseType(type)) {
1073 return false;
1074 }
1075
1076 token = lexer_->PeekToken();
1077 if (token != Token::BRACES_LEFT) {
1078 lexer_->SkipCurrentLine(';');
1079 return false;
1080 }
1081 lexer_->GetToken();
1082
1083 if (!ParseEnumMember(type)) {
1084 return false;
1085 }
1086
1087 token = lexer_->PeekToken();
1088 if (token != Token::SEMICOLON) {
1089 LogError(String::Format("'%s' is not expected.", lexer_->DumpToken().string()));
1090 lexer_->SkipCurrentLine();
1091 return false;
1092 }
1093 lexer_->GetToken();
1094
1095 if (attributes != nullptr) {
1096 type->SetFull(attributes->isFull);
1097 type->SetLite(attributes->isLite);
1098 }
1099
1100 ast_->AddTypeDefinition(type.Get());
1101 return true;
1102 }
1103
ParseEnumBaseType(const AutoPtr<ASTEnumType> & type)1104 bool Parser::ParseEnumBaseType(const AutoPtr<ASTEnumType>& type)
1105 {
1106 Token token = lexer_->PeekToken();
1107 if (token == Token::COLON) {
1108 lexer_->GetToken();
1109 AutoPtr<ASTType> baseType = ParseType();
1110 if (baseType == nullptr) {
1111 LogError("no base type of enum type");
1112 lexer_->SkipCurrentLine(';');
1113 return false;
1114 }
1115 if (baseType->IsByteType() ||
1116 baseType->IsShortType() ||
1117 baseType->IsIntegerType() ||
1118 baseType->IsLongType() ||
1119 baseType->IsUcharType() ||
1120 baseType->IsUshortType() ||
1121 baseType->IsUintType() ||
1122 baseType->IsUlongType()) {
1123 ast_->AddType(baseType);
1124 type->SetBaseType(baseType);
1125 type->SetDisplayBase(true);
1126 } else {
1127 LogError("invaild base type of enum type");
1128 lexer_->SkipCurrentLine(';');
1129 return false;
1130 }
1131 }
1132
1133 if (type->GetBaseType() == nullptr) {
1134 AutoPtr<ASTType> baseType = ast_->FindType("int");
1135 if (baseType == nullptr) {
1136 ast_->AddType(new ASTIntegerType());
1137 baseType = ast_->FindType("int");
1138 }
1139 type->SetBaseType(baseType);
1140 }
1141 return true;
1142 }
1143
ParseEnumMember(const AutoPtr<ASTEnumType> & type)1144 bool Parser::ParseEnumMember(const AutoPtr<ASTEnumType>& type)
1145 {
1146 Token token = lexer_->PeekToken();
1147 while (token != Token::BRACES_RIGHT) {
1148 if (token != Token::IDENTIFIER) {
1149 lexer_->SkipCurrentLine(';');
1150 return false;
1151 }
1152 AutoPtr<ASTEnumValue> enumValue = new ASTEnumValue(lexer_->GetIdentifier());
1153 lexer_->GetToken();
1154
1155 token = lexer_->PeekToken();
1156 if (token == Token::ASSIGN) {
1157 lexer_->GetToken();
1158 token = lexer_->PeekToken();
1159 if (token == Token::DIGIT) {
1160 enumValue->SetValue(lexer_->GetDigit());
1161 lexer_->GetToken();
1162 token = lexer_->PeekToken();
1163 } else {
1164 return false;
1165 }
1166 }
1167
1168 if (token == Token::COMMA) {
1169 lexer_->GetToken();
1170 token = lexer_->PeekToken();
1171 } else if (token == Token::BRACES_RIGHT) {
1172 } else {
1173 lexer_->SkipCurrentLine(';');
1174 return false;
1175 }
1176 enumValue->SetType(type->GetBaseType());
1177 type->AddMember(enumValue);
1178 }
1179 lexer_->GetToken();
1180 return true;
1181 }
1182
ParseStructDefine(const AutoPtr<Attribute> & attributes)1183 bool Parser::ParseStructDefine(const AutoPtr<Attribute>& attributes)
1184 {
1185 lexer_->GetToken();
1186
1187 AutoPtr<ASTStructType> type = new ASTStructType();
1188 if (type == nullptr) {
1189 lexer_->SkipCurrentLine(';');
1190 return false;
1191 }
1192
1193 Token token = lexer_->PeekToken();
1194 if (token != Token::IDENTIFIER) {
1195 LogError(String("custom struct type name is expected."));
1196 return false;
1197 }
1198 type->SetName(lexer_->GetIdentifier());
1199 lexer_->GetToken();
1200
1201 if (!ParseStructMember(type)) {
1202 return false;
1203 }
1204
1205 if (attributes != nullptr) {
1206 type->SetFull(attributes->isFull);
1207 type->SetLite(attributes->isLite);
1208 }
1209
1210 ast_->AddTypeDefinition(type.Get());
1211 return true;
1212 }
1213
ParseStructMember(const AutoPtr<ASTStructType> & type)1214 bool Parser::ParseStructMember(const AutoPtr<ASTStructType>& type)
1215 {
1216 Token token = lexer_->PeekToken();
1217 if (token != Token::BRACES_LEFT) {
1218 lexer_->SkipCurrentLine(';');
1219 return false;
1220 }
1221 lexer_->GetToken();
1222
1223 token = lexer_->PeekToken();
1224 while (token != Token::BRACES_RIGHT) {
1225 AutoPtr<ASTType> member = ParseType();
1226 if (member == nullptr) {
1227 lexer_->SkipCurrentLine(';');
1228 return false;
1229 }
1230 String typeName = member->ToString();
1231
1232 token = lexer_->PeekToken();
1233 if (token != Token::IDENTIFIER) {
1234 LogError(String("member name is expected."));
1235 return false;
1236 }
1237 String memberName = lexer_->GetIdentifier();
1238 lexer_->GetToken();
1239 type->AddMember(member, memberName);
1240
1241 token = lexer_->PeekToken();
1242 if (token == Token::SEMICOLON) {
1243 lexer_->GetToken();
1244 token = lexer_->PeekToken();
1245 } else if (token == Token::BRACES_RIGHT) {
1246 break;
1247 } else {
1248 lexer_->SkipCurrentLine(';');
1249 return false;
1250 }
1251 }
1252 lexer_->GetToken();
1253
1254 token = lexer_->PeekToken();
1255 if (token != Token::SEMICOLON) {
1256 LogError(String::Format("'%s' is not expected.", lexer_->DumpToken().string()));
1257 lexer_->SkipCurrentLine();
1258 return false;
1259 }
1260 lexer_->GetToken();
1261 return true;
1262 }
1263
ParseUnionDefine(const AutoPtr<Attribute> & attributes)1264 bool Parser::ParseUnionDefine(const AutoPtr<Attribute>& attributes)
1265 {
1266 lexer_->GetToken();
1267
1268 AutoPtr<ASTUnionType> type = new ASTUnionType();
1269 if (type == nullptr) {
1270 lexer_->SkipCurrentLine(';');
1271 return false;
1272 }
1273
1274 Token token = lexer_->PeekToken();
1275 if (token != Token::IDENTIFIER) {
1276 LogError(String("custom union type name is expected."));
1277 return false;
1278 }
1279 type->SetName(lexer_->GetIdentifier());
1280 lexer_->GetToken();
1281
1282 if (!ParseUnionMember(type)) {
1283 return false;
1284 }
1285
1286 if (attributes != nullptr) {
1287 type->SetFull(attributes->isFull);
1288 type->SetLite(attributes->isLite);
1289 }
1290
1291 ast_->AddTypeDefinition(type.Get());
1292 return true;
1293 }
1294
ParseUnionMember(const AutoPtr<ASTUnionType> & type)1295 bool Parser::ParseUnionMember(const AutoPtr<ASTUnionType>& type)
1296 {
1297 Token token = lexer_->PeekToken();
1298 if (token != Token::BRACES_LEFT) {
1299 lexer_->SkipCurrentLine(';');
1300 return false;
1301 }
1302 lexer_->GetToken();
1303
1304 token = lexer_->PeekToken();
1305 while (token != Token::BRACES_RIGHT) {
1306 AutoPtr<ASTType> member = ParseType();
1307 if (member == nullptr) {
1308 lexer_->SkipCurrentLine(';');
1309 return false;
1310 }
1311 String typeName = member->ToString();
1312
1313 token = lexer_->PeekToken();
1314 if (token != Token::IDENTIFIER) {
1315 LogError(String("member name is expected."));
1316 return false;
1317 }
1318 String memberName = lexer_->GetIdentifier();
1319 lexer_->GetToken();
1320 type->AddMember(member, memberName);
1321
1322 token = lexer_->PeekToken();
1323 if (token == Token::SEMICOLON) {
1324 lexer_->GetToken();
1325 token = lexer_->PeekToken();
1326 } else if (token == Token::BRACES_RIGHT) {
1327 break;
1328 } else {
1329 lexer_->SkipCurrentLine(';');
1330 return false;
1331 }
1332 }
1333 lexer_->GetToken();
1334
1335 token = lexer_->PeekToken();
1336 if (token != Token::SEMICOLON) {
1337 LogError(String::Format("'%s' is not expected.", lexer_->DumpToken().string()));
1338 lexer_->SkipCurrentLine();
1339 return false;
1340 }
1341 lexer_->GetToken();
1342 return true;
1343 }
1344
CheckType(int lineNo,int columnNo,const AutoPtr<ASTType> & type)1345 bool Parser::CheckType(int lineNo, int columnNo, const AutoPtr<ASTType>& type)
1346 {
1347 if (type == nullptr) {
1348 return false;
1349 }
1350
1351 if (options_.GetTargetLanguage().Equals("c")) {
1352 if (type->IsSequenceableType()) {
1353 LogError(lineNo, columnNo, String::Format("The sequenceable type is not supported by c language."));
1354 return false;
1355 }
1356
1357 if (options_.DoGenerateKernelCode()) {
1358 switch (type->GetTypeKind()) {
1359 case TypeKind::TYPE_FLOAT:
1360 case TypeKind::TYPE_DOUBLE:
1361 case TypeKind::TYPE_FILEDESCRIPTOR:
1362 case TypeKind::TYPE_INTERFACE:
1363 LogError(lineNo, columnNo, String::Format("The '%s' type is not supported by c language.",
1364 lexer_->DumpToken().string()));
1365 break;
1366 default:
1367 break;
1368 }
1369 }
1370 } else if (options_.GetTargetLanguage().Equals("java")) {
1371 switch (type->GetTypeKind()) {
1372 case TypeKind::TYPE_UCHAR:
1373 case TypeKind::TYPE_USHORT:
1374 case TypeKind::TYPE_UINT:
1375 case TypeKind::TYPE_ULONG:
1376 case TypeKind::TYPE_ENUM:
1377 case TypeKind::TYPE_STRUCT:
1378 case TypeKind::TYPE_UNION:
1379 case TypeKind::TYPE_UNKNOWN:
1380 LogError(lineNo, columnNo, String::Format("The '%s' type is not supported by java language.",
1381 lexer_->DumpToken().string()));
1382 return false;
1383 default:
1384 break;
1385 }
1386 }
1387
1388 return true;
1389 }
1390
SetAstFileType()1391 void Parser::SetAstFileType()
1392 {
1393 if (ast_->GetInterfaceDef() != nullptr) {
1394 if (ast_->GetInterfaceDef()->IsCallback()) {
1395 ast_->SetAStFileType(ASTFileType::AST_ICALLBACK);
1396 } else {
1397 ast_->SetAStFileType(ASTFileType::AST_IFACE);
1398 }
1399 } else {
1400 ast_->SetAStFileType(ASTFileType::AST_TYPES);
1401 }
1402 }
1403
CheckIntegrity()1404 bool Parser::CheckIntegrity()
1405 {
1406 if (ast_ == nullptr) {
1407 LogError(String("ast is nullptr."));
1408 return false;
1409 }
1410
1411 if (ast_->GetName().IsEmpty()) {
1412 LogError(String("ast's name is empty."));
1413 return false;
1414 }
1415
1416 if (ast_->GetPackageName().IsEmpty()) {
1417 LogError(String("ast's package name is empty."));
1418 return false;
1419 }
1420
1421 switch (ast_->GetASTFileType()) {
1422 case ASTFileType::AST_IFACE: {
1423 return CheckInterfaceAst();
1424 }
1425 case ASTFileType::AST_ICALLBACK: {
1426 return CheckCallbackAst();
1427 }
1428 case ASTFileType::AST_SEQUENCEABLE: {
1429 LogError(String("it's impossible that ast is sequenceable."));
1430 return false;
1431 }
1432 case ASTFileType::AST_TYPES: {
1433 if (ast_->GetInterfaceDef() != nullptr) {
1434 LogError(String("custom ast cannot has interface."));
1435 return false;
1436 }
1437 break;
1438 }
1439 default:
1440 break;
1441 }
1442
1443 return true;
1444 }
1445
CheckInterfaceAst()1446 bool Parser::CheckInterfaceAst()
1447 {
1448 AutoPtr<ASTInterfaceType> interface = ast_->GetInterfaceDef();
1449 if (interface == nullptr) {
1450 LogError(String("ast's interface is empty."));
1451 return false;
1452 }
1453
1454 if (ast_->GetTypeDefinitionNumber() > 0) {
1455 LogError(String("interface ast cannot has custom types."));
1456 return false;
1457 }
1458
1459 if (interface->GetMethodNumber() == 0) {
1460 LogError(String("interface ast has no method."));
1461 return false;
1462 }
1463 return true;
1464 }
1465
CheckCallbackAst()1466 bool Parser::CheckCallbackAst()
1467 {
1468 AutoPtr<ASTInterfaceType> interface = ast_->GetInterfaceDef();
1469 if (interface == nullptr) {
1470 LogError(String("ast's interface is empty."));
1471 return false;
1472 }
1473
1474 if (!interface->IsCallback()) {
1475 LogError(String("ast is callback, but ast's interface is not callback."));
1476 return false;
1477 }
1478 return true;
1479 }
1480
IsValidTypeName(const String & typeName)1481 bool Parser::IsValidTypeName(const String& typeName)
1482 {
1483 if (typeName[0] == '.') {
1484 return false;
1485 }
1486
1487 if (typeName[typeName.GetLength() - 1] == '.') {
1488 return false;
1489 }
1490
1491 return true;
1492 }
1493
1494 /*
1495 * For example
1496 * filePath: ./ohos/interface/foo/v1_0/IFoo.idl
1497 * package OHOS.Hdi.foo.v1_0;
1498 */
CheckPackageName(const String & filePath,const String & packageName)1499 bool Parser::CheckPackageName(const String& filePath, const String& packageName)
1500 {
1501 String pkgToPath = Options::GetInstance().GetPackagePath(packageName);
1502
1503 int index = filePath.LastIndexOf(File::pathSeparator);
1504 if (index == -1) {
1505 return false;
1506 }
1507
1508 String parentDir = filePath.Substring(0, index);
1509 if (parentDir.IndexOf(pkgToPath) == -1) {
1510 return false;
1511 }
1512
1513 return parentDir.EndsWith(pkgToPath);
1514 }
1515
AddAst()1516 bool Parser::AddAst()
1517 {
1518 if (ast_ == nullptr) {
1519 LogError(String("ast is nullptr."));
1520 return false;
1521 }
1522 astModule_->AddAST(ast_->GetFullName(), ast_);
1523 return true;
1524 }
1525
LogError(const String & message)1526 void Parser::LogError(const String& message)
1527 {
1528 AutoPtr<ErrorInfo> error = new ErrorInfo();
1529
1530 String sourceFile = lexer_->GetFilePath();
1531 #ifdef __MINGW32__
1532 error->file_ = sourceFile.Substring(sourceFile.LastIndexOf('\\') + 1);
1533 #else
1534 error->file_ = sourceFile.Substring(sourceFile.LastIndexOf('/') + 1);
1535 #endif
1536 error->lineNo_ = lexer_->GetTokenLineNumber();
1537 error->columnNo_ = lexer_->GetTokenColumnNumber();
1538 error->message_ = message;
1539
1540 if (errors_ == nullptr) {
1541 errors_ = error;
1542 } else {
1543 AutoPtr<ErrorInfo> pos = errors_;
1544 while (pos->next_ != nullptr) {
1545 pos = pos->next_;
1546 }
1547 pos->next_ = error;
1548 }
1549 }
1550
LogError(int lineNo,int columnNo,const String & message)1551 void Parser::LogError(int lineNo, int columnNo, const String& message)
1552 {
1553 AutoPtr<ErrorInfo> error = new ErrorInfo();
1554
1555 String sourceFile = lexer_->GetFilePath();
1556 #ifdef __MINGW32__
1557 error->file_ = sourceFile.Substring(sourceFile.LastIndexOf('\\') + 1);
1558 #else
1559 error->file_ = sourceFile.Substring(sourceFile.LastIndexOf('/') + 1);
1560 #endif
1561 error->lineNo_ = lineNo;
1562 error->columnNo_ = columnNo;
1563 error->message_ = message;
1564
1565 if (errors_ == nullptr) {
1566 errors_ = error;
1567 } else {
1568 AutoPtr<ErrorInfo> pos = errors_;
1569 while (pos->next_ != nullptr) {
1570 pos = pos->next_;
1571 }
1572 pos->next_ = error;
1573 }
1574 }
1575
ShowError()1576 void Parser::ShowError()
1577 {
1578 AutoPtr<ErrorInfo> error = errors_;
1579 while (error != nullptr) {
1580 Logger::E(TAG, "%s[line %d, column %d] %s", error->file_.string(),
1581 error->lineNo_, error->columnNo_, error->message_.string());
1582 error = error->next_;
1583 }
1584 }
1585 } // namespace HDI
1586 } // namespace OHOS