Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(225)

Side by Side Diff: src/scanner.cc

Issue 5063003: Add separate scanner only intended for preparsing. (Closed)
Patch Set: Address review comments. Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/scanner.h ('k') | src/scanner-base.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 20 matching lines...) Expand all
31 #include "handles.h" 31 #include "handles.h"
32 #include "scanner.h" 32 #include "scanner.h"
33 #include "unicode-inl.h" 33 #include "unicode-inl.h"
34 34
35 namespace v8 { 35 namespace v8 {
36 namespace internal { 36 namespace internal {
37 37
38 // ---------------------------------------------------------------------------- 38 // ----------------------------------------------------------------------------
39 // UTF8Buffer 39 // UTF8Buffer
40 40
41 UTF8Buffer::UTF8Buffer() : buffer_(kInitialCapacity) { } 41 UTF8Buffer::UTF8Buffer() : buffer_(kInitialCapacity), recording_(false) { }
42 42
43 43
44 UTF8Buffer::~UTF8Buffer() {} 44 UTF8Buffer::~UTF8Buffer() {}
45 45
46 46
47 void UTF8Buffer::AddCharSlow(uc32 c) { 47 void UTF8Buffer::AddCharSlow(uc32 c) {
48 ASSERT(static_cast<unsigned>(c) > unibrow::Utf8::kMaxOneByteChar); 48 ASSERT(static_cast<unsigned>(c) > unibrow::Utf8::kMaxOneByteChar);
49 int length = unibrow::Utf8::Length(c); 49 int length = unibrow::Utf8::Length(c);
50 Vector<char> block = buffer_.AddBlock(length, '\0'); 50 Vector<char> block = buffer_.AddBlock(length, '\0');
51 #ifdef DEBUG 51 #ifdef DEBUG
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 } 116 }
117 117
118 118
119 void CharacterStreamUTF16Buffer::SeekForward(int pos) { 119 void CharacterStreamUTF16Buffer::SeekForward(int pos) {
120 pos_ = pos; 120 pos_ = pos;
121 ASSERT(pushback_buffer()->is_empty()); 121 ASSERT(pushback_buffer()->is_empty());
122 stream_->Seek(pos); 122 stream_->Seek(pos);
123 } 123 }
124 124
125 125
126 // ExternalStringUTF16Buffer
127 template <typename StringType, typename CharType>
128 ExternalStringUTF16Buffer<StringType, CharType>::ExternalStringUTF16Buffer()
129 : raw_data_(NULL) { }
130
131
132 template <typename StringType, typename CharType>
133 void ExternalStringUTF16Buffer<StringType, CharType>::Initialize(
134 Handle<StringType> data,
135 int start_position,
136 int end_position) {
137 ASSERT(!data.is_null());
138 raw_data_ = data->resource()->data();
139
140 ASSERT(end_position <= data->length());
141 if (start_position > 0) {
142 SeekForward(start_position);
143 }
144 end_ =
145 end_position != Scanner::kNoEndPosition ? end_position : data->length();
146 }
147
148
149 template <typename StringType, typename CharType>
150 uc32 ExternalStringUTF16Buffer<StringType, CharType>::Advance() {
151 if (pos_ < end_) {
152 return raw_data_[pos_++];
153 } else {
154 // note: currently the following increment is necessary to avoid a
155 // test-parser problem!
156 pos_++;
157 return static_cast<uc32>(-1);
158 }
159 }
160
161
162 template <typename StringType, typename CharType>
163 void ExternalStringUTF16Buffer<StringType, CharType>::PushBack(uc32 ch) {
164 pos_--;
165 ASSERT(pos_ >= Scanner::kCharacterLookaheadBufferSize);
166 ASSERT(raw_data_[pos_ - Scanner::kCharacterLookaheadBufferSize] == ch);
167 }
168
169
170 template <typename StringType, typename CharType>
171 void ExternalStringUTF16Buffer<StringType, CharType>::SeekForward(int pos) {
172 pos_ = pos;
173 }
174
175 // ---------------------------------------------------------------------------- 126 // ----------------------------------------------------------------------------
176 // Scanner::LiteralScope 127 // Scanner::LiteralScope
177 128
178 Scanner::LiteralScope::LiteralScope(Scanner* self) 129 Scanner::LiteralScope::LiteralScope(Scanner* self)
179 : scanner_(self), complete_(false) { 130 : scanner_(self), complete_(false) {
180 self->StartLiteral(); 131 self->StartLiteral();
181 } 132 }
182 133
183 134
184 Scanner::LiteralScope::~LiteralScope() { 135 Scanner::LiteralScope::~LiteralScope() {
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 } 241 }
291 return current_.token; 242 return current_.token;
292 } 243 }
293 244
294 245
295 void Scanner::StartLiteral() { 246 void Scanner::StartLiteral() {
296 literal_buffer_.StartLiteral(); 247 literal_buffer_.StartLiteral();
297 } 248 }
298 249
299 250
300 void Scanner::AddChar(uc32 c) { 251 void Scanner::AddLiteralChar(uc32 c) {
301 literal_buffer_.AddChar(c); 252 literal_buffer_.AddChar(c);
302 } 253 }
303 254
304 255
305 void Scanner::TerminateLiteral() { 256 void Scanner::TerminateLiteral() {
306 next_.literal_chars = literal_buffer_.EndLiteral(); 257 next_.literal_chars = literal_buffer_.EndLiteral();
307 } 258 }
308 259
309 260
310 void Scanner::DropLiteral() { 261 void Scanner::DropLiteral() {
311 literal_buffer_.DropLiteral(); 262 literal_buffer_.DropLiteral();
312 } 263 }
313 264
314 265
315 void Scanner::AddCharAdvance() { 266 void Scanner::AddLiteralCharAdvance() {
316 AddChar(c0_); 267 AddLiteralChar(c0_);
317 Advance(); 268 Advance();
318 } 269 }
319 270
320 271
321 static inline bool IsByteOrderMark(uc32 c) { 272 static inline bool IsByteOrderMark(uc32 c) {
322 // The Unicode value U+FFFE is guaranteed never to be assigned as a 273 // The Unicode value U+FFFE is guaranteed never to be assigned as a
323 // Unicode character; this implies that in a Unicode context the 274 // Unicode character; this implies that in a Unicode context the
324 // 0xFF, 0xFE byte pattern can only be interpreted as the U+FEFF 275 // 0xFF, 0xFE byte pattern can only be interpreted as the U+FEFF
325 // character expressed in little-endian byte order (since it could 276 // character expressed in little-endian byte order (since it could
326 // not be a U+FFFE character expressed in big-endian byte 277 // not be a U+FFFE character expressed in big-endian byte
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
518 469
519 470
520 Token::Value Scanner::ScanJsonString() { 471 Token::Value Scanner::ScanJsonString() {
521 ASSERT_EQ('"', c0_); 472 ASSERT_EQ('"', c0_);
522 Advance(); 473 Advance();
523 LiteralScope literal(this); 474 LiteralScope literal(this);
524 while (c0_ != '"' && c0_ > 0) { 475 while (c0_ != '"' && c0_ > 0) {
525 // Check for control character (0x00-0x1f) or unterminated string (<0). 476 // Check for control character (0x00-0x1f) or unterminated string (<0).
526 if (c0_ < 0x20) return Token::ILLEGAL; 477 if (c0_ < 0x20) return Token::ILLEGAL;
527 if (c0_ != '\\') { 478 if (c0_ != '\\') {
528 AddCharAdvance(); 479 AddLiteralCharAdvance();
529 } else { 480 } else {
530 Advance(); 481 Advance();
531 switch (c0_) { 482 switch (c0_) {
532 case '"': 483 case '"':
533 case '\\': 484 case '\\':
534 case '/': 485 case '/':
535 AddChar(c0_); 486 AddLiteralChar(c0_);
536 break; 487 break;
537 case 'b': 488 case 'b':
538 AddChar('\x08'); 489 AddLiteralChar('\x08');
539 break; 490 break;
540 case 'f': 491 case 'f':
541 AddChar('\x0c'); 492 AddLiteralChar('\x0c');
542 break; 493 break;
543 case 'n': 494 case 'n':
544 AddChar('\x0a'); 495 AddLiteralChar('\x0a');
545 break; 496 break;
546 case 'r': 497 case 'r':
547 AddChar('\x0d'); 498 AddLiteralChar('\x0d');
548 break; 499 break;
549 case 't': 500 case 't':
550 AddChar('\x09'); 501 AddLiteralChar('\x09');
551 break; 502 break;
552 case 'u': { 503 case 'u': {
553 uc32 value = 0; 504 uc32 value = 0;
554 for (int i = 0; i < 4; i++) { 505 for (int i = 0; i < 4; i++) {
555 Advance(); 506 Advance();
556 int digit = HexValue(c0_); 507 int digit = HexValue(c0_);
557 if (digit < 0) { 508 if (digit < 0) {
558 return Token::ILLEGAL; 509 return Token::ILLEGAL;
559 } 510 }
560 value = value * 16 + digit; 511 value = value * 16 + digit;
561 } 512 }
562 AddChar(value); 513 AddLiteralChar(value);
563 break; 514 break;
564 } 515 }
565 default: 516 default:
566 return Token::ILLEGAL; 517 return Token::ILLEGAL;
567 } 518 }
568 Advance(); 519 Advance();
569 } 520 }
570 } 521 }
571 if (c0_ != '"') { 522 if (c0_ != '"') {
572 return Token::ILLEGAL; 523 return Token::ILLEGAL;
573 } 524 }
574 literal.Complete(); 525 literal.Complete();
575 Advance(); 526 Advance();
576 return Token::STRING; 527 return Token::STRING;
577 } 528 }
578 529
579 530
580 Token::Value Scanner::ScanJsonNumber() { 531 Token::Value Scanner::ScanJsonNumber() {
581 LiteralScope literal(this); 532 LiteralScope literal(this);
582 if (c0_ == '-') AddCharAdvance(); 533 if (c0_ == '-') AddLiteralCharAdvance();
583 if (c0_ == '0') { 534 if (c0_ == '0') {
584 AddCharAdvance(); 535 AddLiteralCharAdvance();
585 // Prefix zero is only allowed if it's the only digit before 536 // Prefix zero is only allowed if it's the only digit before
586 // a decimal point or exponent. 537 // a decimal point or exponent.
587 if ('0' <= c0_ && c0_ <= '9') return Token::ILLEGAL; 538 if ('0' <= c0_ && c0_ <= '9') return Token::ILLEGAL;
588 } else { 539 } else {
589 if (c0_ < '1' || c0_ > '9') return Token::ILLEGAL; 540 if (c0_ < '1' || c0_ > '9') return Token::ILLEGAL;
590 do { 541 do {
591 AddCharAdvance(); 542 AddLiteralCharAdvance();
592 } while (c0_ >= '0' && c0_ <= '9'); 543 } while (c0_ >= '0' && c0_ <= '9');
593 } 544 }
594 if (c0_ == '.') { 545 if (c0_ == '.') {
595 AddCharAdvance(); 546 AddLiteralCharAdvance();
596 if (c0_ < '0' || c0_ > '9') return Token::ILLEGAL; 547 if (c0_ < '0' || c0_ > '9') return Token::ILLEGAL;
597 do { 548 do {
598 AddCharAdvance(); 549 AddLiteralCharAdvance();
599 } while (c0_ >= '0' && c0_ <= '9'); 550 } while (c0_ >= '0' && c0_ <= '9');
600 } 551 }
601 if (AsciiAlphaToLower(c0_) == 'e') { 552 if (AsciiAlphaToLower(c0_) == 'e') {
602 AddCharAdvance(); 553 AddLiteralCharAdvance();
603 if (c0_ == '-' || c0_ == '+') AddCharAdvance(); 554 if (c0_ == '-' || c0_ == '+') AddLiteralCharAdvance();
604 if (c0_ < '0' || c0_ > '9') return Token::ILLEGAL; 555 if (c0_ < '0' || c0_ > '9') return Token::ILLEGAL;
605 do { 556 do {
606 AddCharAdvance(); 557 AddLiteralCharAdvance();
607 } while (c0_ >= '0' && c0_ <= '9'); 558 } while (c0_ >= '0' && c0_ <= '9');
608 } 559 }
609 literal.Complete(); 560 literal.Complete();
610 return Token::NUMBER; 561 return Token::NUMBER;
611 } 562 }
612 563
613 564
614 Token::Value Scanner::ScanJsonIdentifier(const char* text, 565 Token::Value Scanner::ScanJsonIdentifier(const char* text,
615 Token::Value token) { 566 Token::Value token) {
616 LiteralScope literal(this); 567 LiteralScope literal(this);
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
951 case '3' : // fall through 902 case '3' : // fall through
952 case '4' : // fall through 903 case '4' : // fall through
953 case '5' : // fall through 904 case '5' : // fall through
954 case '6' : // fall through 905 case '6' : // fall through
955 case '7' : c = ScanOctalEscape(c, 2); break; 906 case '7' : c = ScanOctalEscape(c, 2); break;
956 } 907 }
957 908
958 // According to ECMA-262, 3rd, 7.8.4 (p 18ff) these 909 // According to ECMA-262, 3rd, 7.8.4 (p 18ff) these
959 // should be illegal, but they are commonly handled 910 // should be illegal, but they are commonly handled
960 // as non-escaped characters by JS VMs. 911 // as non-escaped characters by JS VMs.
961 AddChar(c); 912 AddLiteralChar(c);
962 } 913 }
963 914
964 915
965 Token::Value Scanner::ScanString() { 916 Token::Value Scanner::ScanString() {
966 uc32 quote = c0_; 917 uc32 quote = c0_;
967 Advance(); // consume quote 918 Advance(); // consume quote
968 919
969 LiteralScope literal(this); 920 LiteralScope literal(this);
970 while (c0_ != quote && c0_ >= 0 921 while (c0_ != quote && c0_ >= 0
971 && !ScannerConstants::kIsLineTerminator.get(c0_)) { 922 && !ScannerConstants::kIsLineTerminator.get(c0_)) {
972 uc32 c = c0_; 923 uc32 c = c0_;
973 Advance(); 924 Advance();
974 if (c == '\\') { 925 if (c == '\\') {
975 if (c0_ < 0) return Token::ILLEGAL; 926 if (c0_ < 0) return Token::ILLEGAL;
976 ScanEscape(); 927 ScanEscape();
977 } else { 928 } else {
978 AddChar(c); 929 AddLiteralChar(c);
979 } 930 }
980 } 931 }
981 if (c0_ != quote) return Token::ILLEGAL; 932 if (c0_ != quote) return Token::ILLEGAL;
982 literal.Complete(); 933 literal.Complete();
983 934
984 Advance(); // consume quote 935 Advance(); // consume quote
985 return Token::STRING; 936 return Token::STRING;
986 } 937 }
987 938
988 939
(...skipping 10 matching lines...) Expand all
999 return then; 950 return then;
1000 } else { 951 } else {
1001 return else_; 952 return else_;
1002 } 953 }
1003 } 954 }
1004 955
1005 956
1006 // Returns true if any decimal digits were scanned, returns false otherwise. 957 // Returns true if any decimal digits were scanned, returns false otherwise.
1007 void Scanner::ScanDecimalDigits() { 958 void Scanner::ScanDecimalDigits() {
1008 while (IsDecimalDigit(c0_)) 959 while (IsDecimalDigit(c0_))
1009 AddCharAdvance(); 960 AddLiteralCharAdvance();
1010 } 961 }
1011 962
1012 963
1013 Token::Value Scanner::ScanNumber(bool seen_period) { 964 Token::Value Scanner::ScanNumber(bool seen_period) {
1014 ASSERT(IsDecimalDigit(c0_)); // the first digit of the number or the fraction 965 ASSERT(IsDecimalDigit(c0_)); // the first digit of the number or the fraction
1015 966
1016 enum { DECIMAL, HEX, OCTAL } kind = DECIMAL; 967 enum { DECIMAL, HEX, OCTAL } kind = DECIMAL;
1017 968
1018 LiteralScope literal(this); 969 LiteralScope literal(this);
1019 if (seen_period) { 970 if (seen_period) {
1020 // we have already seen a decimal point of the float 971 // we have already seen a decimal point of the float
1021 AddChar('.'); 972 AddLiteralChar('.');
1022 ScanDecimalDigits(); // we know we have at least one digit 973 ScanDecimalDigits(); // we know we have at least one digit
1023 974
1024 } else { 975 } else {
1025 // if the first character is '0' we must check for octals and hex 976 // if the first character is '0' we must check for octals and hex
1026 if (c0_ == '0') { 977 if (c0_ == '0') {
1027 AddCharAdvance(); 978 AddLiteralCharAdvance();
1028 979
1029 // either 0, 0exxx, 0Exxx, 0.xxx, an octal number, or a hex number 980 // either 0, 0exxx, 0Exxx, 0.xxx, an octal number, or a hex number
1030 if (c0_ == 'x' || c0_ == 'X') { 981 if (c0_ == 'x' || c0_ == 'X') {
1031 // hex number 982 // hex number
1032 kind = HEX; 983 kind = HEX;
1033 AddCharAdvance(); 984 AddLiteralCharAdvance();
1034 if (!IsHexDigit(c0_)) { 985 if (!IsHexDigit(c0_)) {
1035 // we must have at least one hex digit after 'x'/'X' 986 // we must have at least one hex digit after 'x'/'X'
1036 return Token::ILLEGAL; 987 return Token::ILLEGAL;
1037 } 988 }
1038 while (IsHexDigit(c0_)) { 989 while (IsHexDigit(c0_)) {
1039 AddCharAdvance(); 990 AddLiteralCharAdvance();
1040 } 991 }
1041 } else if ('0' <= c0_ && c0_ <= '7') { 992 } else if ('0' <= c0_ && c0_ <= '7') {
1042 // (possible) octal number 993 // (possible) octal number
1043 kind = OCTAL; 994 kind = OCTAL;
1044 while (true) { 995 while (true) {
1045 if (c0_ == '8' || c0_ == '9') { 996 if (c0_ == '8' || c0_ == '9') {
1046 kind = DECIMAL; 997 kind = DECIMAL;
1047 break; 998 break;
1048 } 999 }
1049 if (c0_ < '0' || '7' < c0_) break; 1000 if (c0_ < '0' || '7' < c0_) break;
1050 AddCharAdvance(); 1001 AddLiteralCharAdvance();
1051 } 1002 }
1052 } 1003 }
1053 } 1004 }
1054 1005
1055 // Parse decimal digits and allow trailing fractional part. 1006 // Parse decimal digits and allow trailing fractional part.
1056 if (kind == DECIMAL) { 1007 if (kind == DECIMAL) {
1057 ScanDecimalDigits(); // optional 1008 ScanDecimalDigits(); // optional
1058 if (c0_ == '.') { 1009 if (c0_ == '.') {
1059 AddCharAdvance(); 1010 AddLiteralCharAdvance();
1060 ScanDecimalDigits(); // optional 1011 ScanDecimalDigits(); // optional
1061 } 1012 }
1062 } 1013 }
1063 } 1014 }
1064 1015
1065 // scan exponent, if any 1016 // scan exponent, if any
1066 if (c0_ == 'e' || c0_ == 'E') { 1017 if (c0_ == 'e' || c0_ == 'E') {
1067 ASSERT(kind != HEX); // 'e'/'E' must be scanned as part of the hex number 1018 ASSERT(kind != HEX); // 'e'/'E' must be scanned as part of the hex number
1068 if (kind == OCTAL) return Token::ILLEGAL; // no exponent for octals allowed 1019 if (kind == OCTAL) return Token::ILLEGAL; // no exponent for octals allowed
1069 // scan exponent 1020 // scan exponent
1070 AddCharAdvance(); 1021 AddLiteralCharAdvance();
1071 if (c0_ == '+' || c0_ == '-') 1022 if (c0_ == '+' || c0_ == '-')
1072 AddCharAdvance(); 1023 AddLiteralCharAdvance();
1073 if (!IsDecimalDigit(c0_)) { 1024 if (!IsDecimalDigit(c0_)) {
1074 // we must have at least one decimal digit after 'e'/'E' 1025 // we must have at least one decimal digit after 'e'/'E'
1075 return Token::ILLEGAL; 1026 return Token::ILLEGAL;
1076 } 1027 }
1077 ScanDecimalDigits(); 1028 ScanDecimalDigits();
1078 } 1029 }
1079 1030
1080 // The source character immediately following a numeric literal must 1031 // The source character immediately following a numeric literal must
1081 // not be an identifier start or a decimal digit; see ECMA-262 1032 // not be an identifier start or a decimal digit; see ECMA-262
1082 // section 7.8.3, page 17 (note that we read only one decimal digit 1033 // section 7.8.3, page 17 (note that we read only one decimal digit
(...skipping 23 matching lines...) Expand all
1106 ASSERT(ScannerConstants::kIsIdentifierStart.get(c0_)); 1057 ASSERT(ScannerConstants::kIsIdentifierStart.get(c0_));
1107 1058
1108 LiteralScope literal(this); 1059 LiteralScope literal(this);
1109 KeywordMatcher keyword_match; 1060 KeywordMatcher keyword_match;
1110 1061
1111 // Scan identifier start character. 1062 // Scan identifier start character.
1112 if (c0_ == '\\') { 1063 if (c0_ == '\\') {
1113 uc32 c = ScanIdentifierUnicodeEscape(); 1064 uc32 c = ScanIdentifierUnicodeEscape();
1114 // Only allow legal identifier start characters. 1065 // Only allow legal identifier start characters.
1115 if (!ScannerConstants::kIsIdentifierStart.get(c)) return Token::ILLEGAL; 1066 if (!ScannerConstants::kIsIdentifierStart.get(c)) return Token::ILLEGAL;
1116 AddChar(c); 1067 AddLiteralChar(c);
1117 keyword_match.Fail(); 1068 keyword_match.Fail();
1118 } else { 1069 } else {
1119 AddChar(c0_); 1070 AddLiteralChar(c0_);
1120 keyword_match.AddChar(c0_); 1071 keyword_match.AddChar(c0_);
1121 Advance(); 1072 Advance();
1122 } 1073 }
1123 1074
1124 // Scan the rest of the identifier characters. 1075 // Scan the rest of the identifier characters.
1125 while (ScannerConstants::kIsIdentifierPart.get(c0_)) { 1076 while (ScannerConstants::kIsIdentifierPart.get(c0_)) {
1126 if (c0_ == '\\') { 1077 if (c0_ == '\\') {
1127 uc32 c = ScanIdentifierUnicodeEscape(); 1078 uc32 c = ScanIdentifierUnicodeEscape();
1128 // Only allow legal identifier part characters. 1079 // Only allow legal identifier part characters.
1129 if (!ScannerConstants::kIsIdentifierPart.get(c)) return Token::ILLEGAL; 1080 if (!ScannerConstants::kIsIdentifierPart.get(c)) return Token::ILLEGAL;
1130 AddChar(c); 1081 AddLiteralChar(c);
1131 keyword_match.Fail(); 1082 keyword_match.Fail();
1132 } else { 1083 } else {
1133 AddChar(c0_); 1084 AddLiteralChar(c0_);
1134 keyword_match.AddChar(c0_); 1085 keyword_match.AddChar(c0_);
1135 Advance(); 1086 Advance();
1136 } 1087 }
1137 } 1088 }
1138 literal.Complete(); 1089 literal.Complete();
1139 1090
1140 return keyword_match.token(); 1091 return keyword_match.token();
1141 } 1092 }
1142 1093
1143 1094
1144 1095
1145 bool Scanner::ScanRegExpPattern(bool seen_equal) { 1096 bool Scanner::ScanRegExpPattern(bool seen_equal) {
1146 // Scan: ('/' | '/=') RegularExpressionBody '/' RegularExpressionFlags 1097 // Scan: ('/' | '/=') RegularExpressionBody '/' RegularExpressionFlags
1147 bool in_character_class = false; 1098 bool in_character_class = false;
1148 1099
1149 // Previous token is either '/' or '/=', in the second case, the 1100 // Previous token is either '/' or '/=', in the second case, the
1150 // pattern starts at =. 1101 // pattern starts at =.
1151 next_.location.beg_pos = source_pos() - (seen_equal ? 2 : 1); 1102 next_.location.beg_pos = source_pos() - (seen_equal ? 2 : 1);
1152 next_.location.end_pos = source_pos() - (seen_equal ? 1 : 0); 1103 next_.location.end_pos = source_pos() - (seen_equal ? 1 : 0);
1153 1104
1154 // Scan regular expression body: According to ECMA-262, 3rd, 7.8.5, 1105 // Scan regular expression body: According to ECMA-262, 3rd, 7.8.5,
1155 // the scanner should pass uninterpreted bodies to the RegExp 1106 // the scanner should pass uninterpreted bodies to the RegExp
1156 // constructor. 1107 // constructor.
1157 LiteralScope literal(this); 1108 LiteralScope literal(this);
1158 if (seen_equal) 1109 if (seen_equal)
1159 AddChar('='); 1110 AddLiteralChar('=');
1160 1111
1161 while (c0_ != '/' || in_character_class) { 1112 while (c0_ != '/' || in_character_class) {
1162 if (ScannerConstants::kIsLineTerminator.get(c0_) || c0_ < 0) return false; 1113 if (ScannerConstants::kIsLineTerminator.get(c0_) || c0_ < 0) return false;
1163 if (c0_ == '\\') { // escaped character 1114 if (c0_ == '\\') { // escaped character
1164 AddCharAdvance(); 1115 AddLiteralCharAdvance();
1165 if (ScannerConstants::kIsLineTerminator.get(c0_) || c0_ < 0) return false; 1116 if (ScannerConstants::kIsLineTerminator.get(c0_) || c0_ < 0) return false;
1166 AddCharAdvance(); 1117 AddLiteralCharAdvance();
1167 } else { // unescaped character 1118 } else { // unescaped character
1168 if (c0_ == '[') in_character_class = true; 1119 if (c0_ == '[') in_character_class = true;
1169 if (c0_ == ']') in_character_class = false; 1120 if (c0_ == ']') in_character_class = false;
1170 AddCharAdvance(); 1121 AddLiteralCharAdvance();
1171 } 1122 }
1172 } 1123 }
1173 Advance(); // consume '/' 1124 Advance(); // consume '/'
1174 1125
1175 literal.Complete(); 1126 literal.Complete();
1176 1127
1177 return true; 1128 return true;
1178 } 1129 }
1179 1130
1180 bool Scanner::ScanRegExpFlags() { 1131 bool Scanner::ScanRegExpFlags() {
1181 // Scan regular expression flags. 1132 // Scan regular expression flags.
1182 LiteralScope literal(this); 1133 LiteralScope literal(this);
1183 while (ScannerConstants::kIsIdentifierPart.get(c0_)) { 1134 while (ScannerConstants::kIsIdentifierPart.get(c0_)) {
1184 if (c0_ == '\\') { 1135 if (c0_ == '\\') {
1185 uc32 c = ScanIdentifierUnicodeEscape(); 1136 uc32 c = ScanIdentifierUnicodeEscape();
1186 if (c != static_cast<uc32>(unibrow::Utf8::kBadChar)) { 1137 if (c != static_cast<uc32>(unibrow::Utf8::kBadChar)) {
1187 // We allow any escaped character, unlike the restriction on 1138 // We allow any escaped character, unlike the restriction on
1188 // IdentifierPart when it is used to build an IdentifierName. 1139 // IdentifierPart when it is used to build an IdentifierName.
1189 AddChar(c); 1140 AddLiteralChar(c);
1190 continue; 1141 continue;
1191 } 1142 }
1192 } 1143 }
1193 AddCharAdvance(); 1144 AddLiteralCharAdvance();
1194 } 1145 }
1195 literal.Complete(); 1146 literal.Complete();
1196 1147
1197 next_.location.end_pos = source_pos() - 1; 1148 next_.location.end_pos = source_pos() - 1;
1198 return true; 1149 return true;
1199 } 1150 }
1200 1151
1201 } } // namespace v8::internal 1152 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/scanner.h ('k') | src/scanner-base.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698