OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/regexp/regexp-parser.h" | 5 #include "src/regexp/regexp-parser.h" |
6 | 6 |
7 #include "src/char-predicates-inl.h" | 7 #include "src/char-predicates-inl.h" |
8 #include "src/factory.h" | 8 #include "src/factory.h" |
9 #include "src/isolate.h" | 9 #include "src/isolate.h" |
10 #include "src/objects-inl.h" | 10 #include "src/objects-inl.h" |
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 uc32 c = Next(); | 345 uc32 c = Next(); |
346 Advance(2); | 346 Advance(2); |
347 ZoneList<CharacterRange>* ranges = | 347 ZoneList<CharacterRange>* ranges = |
348 new (zone()) ZoneList<CharacterRange>(2, zone()); | 348 new (zone()) ZoneList<CharacterRange>(2, zone()); |
349 CharacterRange::AddClassEscape(c, ranges, zone()); | 349 CharacterRange::AddClassEscape(c, ranges, zone()); |
350 RegExpCharacterClass* cc = | 350 RegExpCharacterClass* cc = |
351 new (zone()) RegExpCharacterClass(ranges, false); | 351 new (zone()) RegExpCharacterClass(ranges, false); |
352 builder->AddCharacterClass(cc); | 352 builder->AddCharacterClass(cc); |
353 break; | 353 break; |
354 } | 354 } |
| 355 case 'p': |
| 356 case 'P': { |
| 357 uc32 p = Next(); |
| 358 Advance(2); |
| 359 if (unicode()) { |
| 360 ZoneList<CharacterRange>* ranges = ParsePropertyClass(); |
| 361 if (ranges == nullptr) { |
| 362 return ReportError(CStrVector("Invalid property name")); |
| 363 } |
| 364 RegExpCharacterClass* cc = |
| 365 new (zone()) RegExpCharacterClass(ranges, p == 'P'); |
| 366 builder->AddCharacterClass(cc); |
| 367 } else { |
| 368 builder->AddCharacter(p); |
| 369 } |
| 370 break; |
| 371 } |
355 case '1': | 372 case '1': |
356 case '2': | 373 case '2': |
357 case '3': | 374 case '3': |
358 case '4': | 375 case '4': |
359 case '5': | 376 case '5': |
360 case '6': | 377 case '6': |
361 case '7': | 378 case '7': |
362 case '8': | 379 case '8': |
363 case '9': { | 380 case '9': { |
364 int index = 0; | 381 int index = 0; |
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
794 return true; | 811 return true; |
795 } | 812 } |
796 } | 813 } |
797 Reset(start); | 814 Reset(start); |
798 return false; | 815 return false; |
799 } | 816 } |
800 // \u but no {, or \u{...} escapes not allowed. | 817 // \u but no {, or \u{...} escapes not allowed. |
801 return ParseHexEscape(4, value); | 818 return ParseHexEscape(4, value); |
802 } | 819 } |
803 | 820 |
| 821 ZoneList<CharacterRange>* RegExpParser::ParsePropertyClass() { |
| 822 #ifdef V8_I18N_SUPPORT |
| 823 char property_name[3]; |
| 824 memset(property_name, 0, sizeof(property_name)); |
| 825 if (current() == '{') { |
| 826 Advance(); |
| 827 if (current() < 'A' || current() > 'Z') return nullptr; |
| 828 property_name[0] = static_cast<char>(current()); |
| 829 Advance(); |
| 830 if (current() >= 'a' && current() <= 'z') { |
| 831 property_name[1] = static_cast<char>(current()); |
| 832 Advance(); |
| 833 } |
| 834 if (current() != '}') return nullptr; |
| 835 } else if (current() >= 'A' && current() <= 'Z') { |
| 836 property_name[0] = static_cast<char>(current()); |
| 837 } else { |
| 838 return nullptr; |
| 839 } |
| 840 Advance(); |
| 841 |
| 842 int32_t category = |
| 843 u_getPropertyValueEnum(UCHAR_GENERAL_CATEGORY_MASK, property_name); |
| 844 if (category == UCHAR_INVALID_CODE) return nullptr; |
| 845 |
| 846 USet* set = uset_openEmpty(); |
| 847 UErrorCode ec = U_ZERO_ERROR; |
| 848 uset_applyIntPropertyValue(set, UCHAR_GENERAL_CATEGORY_MASK, category, &ec); |
| 849 ZoneList<CharacterRange>* ranges = nullptr; |
| 850 if (ec == U_ZERO_ERROR && !uset_isEmpty(set)) { |
| 851 uset_removeAllStrings(set); |
| 852 int item_count = uset_getItemCount(set); |
| 853 ranges = new (zone()) ZoneList<CharacterRange>(item_count, zone()); |
| 854 int item_result = 0; |
| 855 for (int i = 0; i < item_count; i++) { |
| 856 uc32 start = 0; |
| 857 uc32 end = 0; |
| 858 item_result += uset_getItem(set, i, &start, &end, nullptr, 0, &ec); |
| 859 ranges->Add(CharacterRange::Range(start, end), zone()); |
| 860 } |
| 861 DCHECK_EQ(U_ZERO_ERROR, ec); |
| 862 DCHECK_EQ(0, item_result); |
| 863 } |
| 864 uset_close(set); |
| 865 return ranges; |
| 866 #else // V8_I18N_SUPPORT |
| 867 return nullptr; |
| 868 #endif // V8_I18N_SUPPORT |
| 869 } |
804 | 870 |
805 bool RegExpParser::ParseUnlimitedLengthHexNumber(int max_value, uc32* value) { | 871 bool RegExpParser::ParseUnlimitedLengthHexNumber(int max_value, uc32* value) { |
806 uc32 x = 0; | 872 uc32 x = 0; |
807 int d = HexValue(current()); | 873 int d = HexValue(current()); |
808 if (d < 0) { | 874 if (d < 0) { |
809 return false; | 875 return false; |
810 } | 876 } |
811 while (d >= 0) { | 877 while (d >= 0) { |
812 x = x * 16 + d; | 878 x = x * 16 + d; |
813 if (x > max_value) { | 879 if (x > max_value) { |
(...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1362 return false; | 1428 return false; |
1363 } | 1429 } |
1364 terms_.Add(new (zone()) RegExpQuantifier(min, max, quantifier_type, atom), | 1430 terms_.Add(new (zone()) RegExpQuantifier(min, max, quantifier_type, atom), |
1365 zone()); | 1431 zone()); |
1366 LAST(ADD_TERM); | 1432 LAST(ADD_TERM); |
1367 return true; | 1433 return true; |
1368 } | 1434 } |
1369 | 1435 |
1370 } // namespace internal | 1436 } // namespace internal |
1371 } // namespace v8 | 1437 } // namespace v8 |
OLD | NEW |