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