1 /* 2 * Copyright (c) 2021 - 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 "ETSLexer.h" 17 #include "generated/keywords.h" 18 19 namespace ark::es2panda::lexer { 20 // NOLINTNEXTLINE(google-default-arguments) NextToken(NextTokenFlags flags)21void ETSLexer::NextToken(NextTokenFlags flags) 22 { 23 ETSKeywords kws(this, static_cast<NextTokenFlags>(flags & ~NextTokenFlags::KEYWORD_TO_IDENT)); 24 Lexer::NextToken(&kws); 25 } 26 ScanHashMark()27void ETSLexer::ScanHashMark() 28 { 29 LogUnexpectedToken(TokenType::PUNCTUATOR_HASH_MARK); 30 } 31 ScanCharLiteral()32bool ETSLexer::ScanCharLiteral() 33 { 34 // Note: for character literal on call iterator is pointed to the opening single quote (') character! 35 // Otherwise it's another token. 36 bool status = true; 37 38 if (Iterator().Peek() != LEX_CHAR_SINGLE_QUOTE) { 39 return false; 40 } 41 42 GetToken().type_ = TokenType::LITERAL_CHAR; 43 44 Iterator().Forward(1); 45 char32_t cp = Iterator().PeekCp(); 46 47 switch (cp) { 48 case LEX_CHAR_SINGLE_QUOTE: 49 case util::StringView::Iterator::INVALID_CP: { 50 LogSyntaxError("Invalid character literal"); 51 status = false; 52 break; 53 } 54 case LEX_CHAR_BACKSLASH: { 55 GetToken().flags_ |= TokenFlags::HAS_ESCAPE; 56 57 Iterator().Forward(1); 58 cp = ScanUnicodeCharacter(); 59 break; 60 } 61 default: { 62 Iterator().SkipCp(); 63 break; 64 } 65 } 66 67 if (CheckUtf16Compatible(cp)) { 68 GetToken().c16_ = cp; 69 } 70 71 if (Iterator().Peek() != LEX_CHAR_SINGLE_QUOTE) { 72 LogSyntaxError("Unterminated character literal"); 73 return false; 74 } 75 76 Iterator().Forward(1); 77 return status; 78 } 79 CheckNumberLiteralEnd()80void ETSLexer::CheckNumberLiteralEnd() 81 { 82 if (Iterator().Peek() == LEX_CHAR_LOWERCASE_F) { 83 GetToken().flags_ |= TokenFlags::NUMBER_FLOAT; 84 GetToken().src_ = SourceView(GetToken().Start().index, Iterator().Index()); 85 Iterator().Forward(1); 86 const auto nextCp = Iterator().PeekCp(); 87 if (KeywordsUtil::IsIdentifierStart(nextCp) || IsDecimalDigit(nextCp)) { 88 LogSyntaxError("Invalid numeric literal"); 89 Iterator().Forward(1); // Error processing 90 } 91 } else { 92 Lexer::CheckNumberLiteralEnd(); 93 } 94 } 95 CheckUtf16Compatible(char32_t cp) const96bool ETSLexer::CheckUtf16Compatible(char32_t cp) const 97 { 98 if (cp >= util::StringView::Constants::CELESTIAL_OFFSET) { 99 // lexer_invalid_characters.sts 100 LogSyntaxError("Unsupported character literal"); 101 return false; 102 } 103 return true; 104 } 105 ScanAsteriskPunctuator()106void ETSLexer::ScanAsteriskPunctuator() 107 { 108 GetToken().type_ = TokenType::PUNCTUATOR_MULTIPLY; 109 110 switch (Iterator().Peek()) { 111 case LEX_CHAR_EQUALS: { 112 GetToken().type_ = TokenType::PUNCTUATOR_MULTIPLY_EQUAL; 113 Iterator().Forward(1); 114 break; 115 } 116 default: { 117 break; 118 } 119 } 120 } 121 ConvertNumber(NumberFlags const flags)122void ETSLexer::ConvertNumber(NumberFlags const flags) 123 { 124 GetToken().number_ = lexer::Number(GetToken().src_, flags); 125 if (GetToken().number_.ConversionError()) { 126 LogSyntaxError("Invalid number"); 127 } 128 } 129 ScanEqualsPunctuator()130void ETSLexer::ScanEqualsPunctuator() 131 { 132 GetToken().type_ = TokenType::PUNCTUATOR_SUBSTITUTION; 133 134 switch (Iterator().Peek()) { 135 case LEX_CHAR_EQUALS: { 136 GetToken().type_ = TokenType::PUNCTUATOR_EQUAL; 137 Iterator().Forward(1); 138 139 if (Iterator().Peek() == LEX_CHAR_EQUALS) { 140 GetToken().type_ = TokenType::PUNCTUATOR_STRICT_EQUAL; 141 Iterator().Forward(1); 142 } 143 break; 144 } 145 case LEX_CHAR_GREATER_THAN: { 146 GetToken().type_ = TokenType::PUNCTUATOR_ARROW; 147 Iterator().Forward(1); 148 break; 149 } 150 default: { 151 break; 152 } 153 } 154 } 155 ScanExclamationPunctuator()156void ETSLexer::ScanExclamationPunctuator() 157 { 158 GetToken().type_ = TokenType::PUNCTUATOR_EXCLAMATION_MARK; 159 160 switch (Iterator().Peek()) { 161 case LEX_CHAR_EQUALS: { 162 GetToken().type_ = TokenType::PUNCTUATOR_NOT_EQUAL; 163 Iterator().Forward(1); 164 165 if (Iterator().Peek() == LEX_CHAR_EQUALS) { 166 GetToken().type_ = TokenType::PUNCTUATOR_NOT_STRICT_EQUAL; 167 Iterator().Forward(1); 168 } 169 break; 170 } 171 default: { 172 break; 173 } 174 } 175 } 176 ScanDollarPunctuator()177bool ETSLexer::ScanDollarPunctuator() 178 { 179 if (Iterator().Peek() != LEX_CHAR_DOLLAR_SIGN) { 180 return false; 181 } 182 183 GetToken().type_ = TokenType::PUNCTUATOR_DOLLAR_DOLLAR; 184 Iterator().Forward(1); 185 return true; 186 } 187 } // namespace ark::es2panda::lexer 188