Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
RegexParser.cs
Go to the documentation of this file.
4
6
7internal ref struct RegexParser
8{
10
12
14
16
18
19 private readonly string _pattern;
20
21 private int _currentPos;
22
23 private readonly CultureInfo _culture;
24
25 private int _autocap;
26
27 private int _capcount;
28
29 private int _captop;
30
31 private readonly int _capsize;
32
33 private readonly Hashtable _caps;
34
36
37 private int[] _capnumlist;
38
40
42
44
45 private bool _ignoreNextParen;
46
47 private static ReadOnlySpan<byte> Category => new byte[128]
48 {
49 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,
50 2, 0, 2, 2, 0, 0, 0, 0, 0, 0,
51 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
52 0, 0, 2, 0, 0, 3, 4, 0, 0, 0,
53 4, 4, 5, 5, 0, 0, 4, 0, 0, 0,
54 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
55 0, 0, 0, 5, 0, 0, 0, 0, 0, 0,
56 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
57 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
58 0, 4, 4, 0, 4, 0, 0, 0, 0, 0,
59 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
60 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
61 0, 0, 0, 5, 4, 0, 0, 0
62 };
63
65 {
69 _caps = caps;
70 _capsize = capsize;
71 _capnames = capnames;
73 _stack = null;
74 _group = null;
75 _alternation = null;
76 _concatenation = null;
77 _unit = null;
78 _currentPos = 0;
79 _autocap = 0;
80 _capcount = 0;
81 _captop = 0;
82 _capnumlist = null;
83 _capnamelist = null;
84 _ignoreNextParen = false;
85 }
86
91
93 {
96 regexParser.CountCaptures();
97 regexParser.Reset(options);
98 RegexNode regexNode = regexParser.ScanRegex();
99 int minRequiredLength = regexNode.ComputeMinLength();
100 string[] capsList = regexParser._capnamelist?.ToArray();
101 RegexTree result = new RegexTree(regexNode, regexParser._caps, regexParser._capnumlist, regexParser._captop, regexParser._capnames, capsList, options, minRequiredLength);
102 regexParser.Dispose();
103 return result;
104 }
105
106 public static RegexReplacement ParseReplacement(string pattern, RegexOptions options, Hashtable caps, int capsize, Hashtable capnames)
107 {
108 CultureInfo cultureInfo = (((options & RegexOptions.CultureInvariant) != 0) ? CultureInfo.InvariantCulture : CultureInfo.CurrentCulture);
111 RegexParser regexParser = new RegexParser(pattern, options, culture, caps, capsize, capnames, optionSpan);
112 RegexNode concat = regexParser.ScanReplacement();
113 RegexReplacement result = new RegexReplacement(pattern, concat, caps);
114 regexParser.Dispose();
115 return result;
116 }
117
118 public static string Escape(string input)
119 {
120 for (int i = 0; i < input.Length; i++)
121 {
122 if (IsMetachar(input[i]))
123 {
124 return EscapeImpl(input, i);
125 }
126 }
127 return input;
128 }
129
130 private static string EscapeImpl(string input, int i)
131 {
133 if (input.Length <= 85)
134 {
137 }
138 else
139 {
141 }
143 char c = input[i];
144 valueStringBuilder2.Append(input.AsSpan(0, i));
145 do
146 {
147 valueStringBuilder2.Append('\\');
148 switch (c)
149 {
150 case '\n':
151 c = 'n';
152 break;
153 case '\r':
154 c = 'r';
155 break;
156 case '\t':
157 c = 't';
158 break;
159 case '\f':
160 c = 'f';
161 break;
162 }
163 valueStringBuilder2.Append(c);
164 i++;
165 int num = i;
166 while (i < input.Length)
167 {
168 c = input[i];
169 if (IsMetachar(c))
170 {
171 break;
172 }
173 i++;
174 }
175 valueStringBuilder2.Append(input.AsSpan(num, i - num));
176 }
177 while (i < input.Length);
178 return valueStringBuilder2.ToString();
179 }
180
181 public static string Unescape(string input)
182 {
183 int num = input.IndexOf('\\');
184 if (num < 0)
185 {
186 return input;
187 }
188 return UnescapeImpl(input, num);
189 }
190
191 private static string UnescapeImpl(string input, int i)
192 {
197 if (input.Length <= 256)
198 {
201 }
202 else
203 {
205 }
207 valueStringBuilder2.Append(input.AsSpan(0, i));
208 do
209 {
210 i++;
211 regexParser.Textto(i);
212 if (i < input.Length)
213 {
214 valueStringBuilder2.Append(regexParser.ScanCharEscape());
215 }
216 i = regexParser.Textpos();
217 int num = i;
218 while (i < input.Length && input[i] != '\\')
219 {
220 i++;
221 }
222 valueStringBuilder2.Append(input.AsSpan(num, i - num));
223 }
224 while (i < input.Length);
225 regexParser.Dispose();
226 return valueStringBuilder2.ToString();
227 }
228
230 {
231 _currentPos = 0;
232 _autocap = 1;
233 _ignoreNextParen = false;
234 _optionsStack.Length = 0;
236 _stack = null;
237 }
238
239 public void Dispose()
240 {
241 _optionsStack.Dispose();
242 }
243
245 {
246 char c = '@';
247 bool flag = false;
248 StartGroup(new RegexNode(28, _options, 0, -1));
249 while (CharsRight() > 0)
250 {
251 bool flag2 = flag;
252 flag = false;
253 ScanBlank();
254 int num = Textpos();
255 if (UseOptionX())
256 {
257 while (CharsRight() > 0 && (!IsStopperX(c = RightChar()) || (c == '{' && !IsTrueQuantifier())))
258 {
259 MoveRight();
260 }
261 }
262 else
263 {
264 while (CharsRight() > 0 && (!IsSpecial(c = RightChar()) || (c == '{' && !IsTrueQuantifier())))
265 {
266 MoveRight();
267 }
268 }
269 int num2 = Textpos();
270 ScanBlank();
271 if (CharsRight() == 0)
272 {
273 c = '!';
274 }
275 else if (IsSpecial(c = RightChar()))
276 {
277 flag = IsQuantifier(c);
278 MoveRight();
279 }
280 else
281 {
282 c = ' ';
283 }
284 if (num < num2)
285 {
286 int num3 = num2 - num - (flag ? 1 : 0);
287 flag2 = false;
288 if (num3 > 0)
289 {
290 AddConcatenate(num, num3, isReplacement: false);
291 }
292 if (flag)
293 {
294 AddUnitOne(CharAt(num2 - 1));
295 }
296 }
297 switch (c)
298 {
299 case '[':
300 AddUnitSet(ScanCharClass(UseOptionI(), scanOnly: false).ToStringClass());
301 goto IL_02cf;
302 case '(':
303 {
304 PushOptions();
306 if ((openGroup = ScanGroupOpen()) == null)
307 {
309 continue;
310 }
311 PushGroup();
313 continue;
314 }
315 case '|':
316 AddAlternate();
317 continue;
318 case ')':
319 if (EmptyStack())
320 {
321 throw MakeException(RegexParseError.InsufficientOpeningParentheses, System.SR.InsufficientOpeningParentheses);
322 }
323 AddGroup();
324 PopGroup();
325 PopOptions();
326 if (Unit() == null)
327 {
328 continue;
329 }
330 goto IL_02cf;
331 case '\\':
332 if (CharsRight() == 0)
333 {
334 throw MakeException(RegexParseError.UnescapedEndingBackslash, System.SR.UnescapedEndingBackslash);
335 }
337 goto IL_02cf;
338 case '^':
339 AddUnitType(UseOptionM() ? 14 : 18);
340 goto IL_02cf;
341 case '$':
342 AddUnitType(UseOptionM() ? 15 : 20);
343 goto IL_02cf;
344 case '.':
345 if (UseOptionS())
346 {
347 AddUnitSet("\0\u0001\0\0");
348 }
349 else
350 {
351 AddUnitNotone('\n');
352 }
353 goto IL_02cf;
354 case '*':
355 case '+':
356 case '?':
357 case '{':
358 if (Unit() == null)
359 {
361 }
362 MoveLeft();
363 goto IL_02cf;
364 default:
366 case ' ':
367 continue;
368 case '!':
369 break;
370 IL_02cf:
371 ScanBlank();
372 if (CharsRight() == 0 || !(flag = IsTrueQuantifier()))
373 {
375 continue;
376 }
377 c = RightCharMoveRight();
378 while (Unit() != null)
379 {
380 int num4;
381 int num5;
382 if ((uint)c <= 43u)
383 {
384 if (c != '*')
385 {
386 if (c != '+')
387 {
388 goto IL_03cd;
389 }
390 num4 = 1;
391 num5 = int.MaxValue;
392 }
393 else
394 {
395 num4 = 0;
396 num5 = int.MaxValue;
397 }
398 }
399 else if (c != '?')
400 {
401 if (c != '{')
402 {
403 goto IL_03cd;
404 }
405 num = Textpos();
406 num5 = (num4 = ScanDecimal());
407 if (num < Textpos() && CharsRight() > 0 && RightChar() == ',')
408 {
409 MoveRight();
410 num5 = ((CharsRight() != 0 && RightChar() != '}') ? ScanDecimal() : int.MaxValue);
411 }
412 if (num == Textpos() || CharsRight() == 0 || RightCharMoveRight() != '}')
413 {
415 Textto(num - 1);
416 break;
417 }
418 }
419 else
420 {
421 num4 = 0;
422 num5 = 1;
423 }
424 ScanBlank();
425 bool lazy = false;
426 if (CharsRight() != 0 && RightChar() == '?')
427 {
428 MoveRight();
429 lazy = true;
430 }
431 if (num4 > num5)
432 {
433 throw MakeException(RegexParseError.ReversedQuantifierRange, System.SR.ReversedQuantifierRange);
434 }
436 continue;
437 IL_03cd:
439 }
440 continue;
441 }
442 break;
443 }
444 if (!EmptyStack())
445 {
446 throw MakeException(RegexParseError.InsufficientClosingParentheses, System.SR.InsufficientClosingParentheses);
447 }
448 AddGroup();
449 return Unit().FinalOptimize();
450 }
451
453 {
455 while (true)
456 {
457 int num = CharsRight();
458 if (num == 0)
459 {
460 break;
461 }
462 int num2 = Textpos();
463 while (num > 0 && RightChar() != '$')
464 {
465 MoveRight();
466 num--;
467 }
469 if (num > 0)
470 {
471 if (RightCharMoveRight() == '$')
472 {
474 }
476 }
477 }
478 return _concatenation;
479 }
480
481 private RegexCharClass ScanCharClass(bool caseInsensitive, bool scanOnly)
482 {
483 char c = '\0';
484 char c2 = '\0';
485 bool flag = false;
486 bool flag2 = true;
487 bool flag3 = false;
489 if (CharsRight() > 0 && RightChar() == '^')
490 {
491 MoveRight();
492 if (!scanOnly)
493 {
494 regexCharClass.Negate = true;
495 }
496 if ((_options & RegexOptions.ECMAScript) != 0 && CharAt(_currentPos) == ']')
497 {
498 flag2 = false;
499 }
500 }
501 for (; CharsRight() > 0; flag2 = false)
502 {
503 bool flag4 = false;
504 c = RightCharMoveRight();
505 if (c == ']')
506 {
507 if (!flag2)
508 {
509 flag3 = true;
510 break;
511 }
512 }
513 else if (c == '\\' && CharsRight() > 0)
514 {
515 switch (c = RightCharMoveRight())
516 {
517 case 'D':
518 case 'd':
519 if (!scanOnly)
520 {
521 if (flag)
522 {
523 throw MakeException(RegexParseError.ShorthandClassInCharacterRange, System.SR.Format(System.SR.ShorthandClassInCharacterRange, c));
524 }
525 regexCharClass.AddDigit(UseOptionE(), c == 'D', _pattern, _currentPos);
526 }
527 continue;
528 case 'S':
529 case 's':
530 if (!scanOnly)
531 {
532 if (flag)
533 {
534 throw MakeException(RegexParseError.ShorthandClassInCharacterRange, System.SR.Format(System.SR.ShorthandClassInCharacterRange, c));
535 }
536 regexCharClass.AddSpace(UseOptionE(), c == 'S');
537 }
538 continue;
539 case 'W':
540 case 'w':
541 if (!scanOnly)
542 {
543 if (flag)
544 {
545 throw MakeException(RegexParseError.ShorthandClassInCharacterRange, System.SR.Format(System.SR.ShorthandClassInCharacterRange, c));
546 }
547 regexCharClass.AddWord(UseOptionE(), c == 'W');
548 }
549 continue;
550 case 'P':
551 case 'p':
552 if (!scanOnly)
553 {
554 if (flag)
555 {
556 throw MakeException(RegexParseError.ShorthandClassInCharacterRange, System.SR.Format(System.SR.ShorthandClassInCharacterRange, c));
557 }
558 regexCharClass.AddCategoryFromName(ParseProperty(), c != 'p', caseInsensitive, _pattern, _currentPos);
559 }
560 else
561 {
563 }
564 continue;
565 case '-':
566 if (scanOnly)
567 {
568 continue;
569 }
570 if (flag)
571 {
572 if (c2 > c)
573 {
574 throw MakeException(RegexParseError.ReversedCharacterRange, System.SR.ReversedCharacterRange);
575 }
577 flag = false;
578 c2 = '\0';
579 }
580 else
581 {
583 }
584 continue;
585 }
586 MoveLeft();
587 c = ScanCharEscape();
588 flag4 = true;
589 }
590 else if (c == '[' && CharsRight() > 0 && RightChar() == ':' && !flag)
591 {
592 int pos = Textpos();
593 MoveRight();
594 if (CharsRight() < 2 || RightCharMoveRight() != ':' || RightCharMoveRight() != ']')
595 {
596 Textto(pos);
597 }
598 }
599 if (flag)
600 {
601 flag = false;
602 if (scanOnly)
603 {
604 continue;
605 }
606 if (c == '[' && !flag4 && !flag2)
607 {
608 regexCharClass.AddChar(c2);
609 regexCharClass.AddSubtraction(ScanCharClass(caseInsensitive, scanOnly));
610 if (CharsRight() > 0 && RightChar() != ']')
611 {
612 throw MakeException(RegexParseError.ExclusionGroupNotLast, System.SR.ExclusionGroupNotLast);
613 }
614 }
615 else
616 {
617 if (c2 > c)
618 {
619 throw MakeException(RegexParseError.ReversedCharacterRange, System.SR.ReversedCharacterRange);
620 }
622 }
623 }
624 else if (CharsRight() >= 2 && RightChar() == '-' && RightChar(1) != ']')
625 {
626 c2 = c;
627 flag = true;
628 MoveRight();
629 }
630 else if (CharsRight() >= 1 && c == '-' && !flag4 && RightChar() == '[' && !flag2)
631 {
632 if (!scanOnly)
633 {
634 MoveRight(1);
635 regexCharClass.AddSubtraction(ScanCharClass(caseInsensitive, scanOnly));
636 if (CharsRight() > 0 && RightChar() != ']')
637 {
638 throw MakeException(RegexParseError.ExclusionGroupNotLast, System.SR.ExclusionGroupNotLast);
639 }
640 }
641 else
642 {
643 MoveRight(1);
644 ScanCharClass(caseInsensitive, scanOnly);
645 }
646 }
647 else if (!scanOnly)
648 {
650 }
651 }
652 if (!flag3)
653 {
654 throw MakeException(RegexParseError.UnterminatedBracket, System.SR.UnterminatedBracket);
655 }
656 if (!scanOnly && caseInsensitive)
657 {
658 regexCharClass.AddLowercase(_culture);
659 }
660 return regexCharClass;
661 }
662
664 {
665 if (CharsRight() == 0 || RightChar() != '?' || (RightChar() == '?' && CharsRight() > 1 && RightChar(1) == ')'))
666 {
668 {
669 _ignoreNextParen = false;
670 return new RegexNode(29, _options);
671 }
672 return new RegexNode(28, _options, _autocap++, -1);
673 }
674 MoveRight();
675 if (CharsRight() != 0)
676 {
677 char c = '>';
678 int type;
679 switch (RightCharMoveRight())
680 {
681 case ':':
682 type = 29;
683 goto IL_0501;
684 case '=':
685 _options &= ~RegexOptions.RightToLeft;
686 type = 30;
687 goto IL_0501;
688 case '!':
689 _options &= ~RegexOptions.RightToLeft;
690 type = 31;
691 goto IL_0501;
692 case '>':
693 type = 32;
694 goto IL_0501;
695 case '\'':
696 c = '\'';
697 goto case '<';
698 case '<':
699 {
700 if (CharsRight() == 0)
701 {
702 break;
703 }
704 char c2;
705 char c3 = (c2 = RightCharMoveRight());
706 if (c3 != '!')
707 {
708 if (c3 != '=')
709 {
710 MoveLeft();
711 int num = -1;
712 int num2 = -1;
713 bool flag = false;
714 if ((uint)(c2 - 48) <= 9u)
715 {
716 num = ScanDecimal();
717 if (!IsCaptureSlot(num))
718 {
719 num = -1;
720 }
721 if (CharsRight() > 0 && RightChar() != c && RightChar() != '-')
722 {
723 throw MakeException(RegexParseError.CaptureGroupNameInvalid, System.SR.CaptureGroupNameInvalid);
724 }
725 if (num == 0)
726 {
727 throw MakeException(RegexParseError.CaptureGroupOfZero, System.SR.CaptureGroupOfZero);
728 }
729 }
730 else if (RegexCharClass.IsWordChar(c2))
731 {
732 string capname = ScanCapname();
734 {
736 }
737 if (CharsRight() > 0 && RightChar() != c && RightChar() != '-')
738 {
739 throw MakeException(RegexParseError.CaptureGroupNameInvalid, System.SR.CaptureGroupNameInvalid);
740 }
741 }
742 else
743 {
744 if (c2 != '-')
745 {
746 throw MakeException(RegexParseError.CaptureGroupNameInvalid, System.SR.CaptureGroupNameInvalid);
747 }
748 flag = true;
749 }
750 if ((num != -1 || flag) && CharsRight() > 1 && RightChar() == '-')
751 {
752 MoveRight();
753 c2 = RightChar();
754 if ((uint)(c2 - 48) <= 9u)
755 {
756 num2 = ScanDecimal();
757 if (!IsCaptureSlot(num2))
758 {
760 }
761 if (CharsRight() > 0 && RightChar() != c)
762 {
763 throw MakeException(RegexParseError.CaptureGroupNameInvalid, System.SR.CaptureGroupNameInvalid);
764 }
765 }
766 else
767 {
769 {
770 throw MakeException(RegexParseError.CaptureGroupNameInvalid, System.SR.CaptureGroupNameInvalid);
771 }
772 string text = ScanCapname();
773 if (!IsCaptureName(text))
774 {
776 }
778 if (CharsRight() > 0 && RightChar() != c)
779 {
780 throw MakeException(RegexParseError.CaptureGroupNameInvalid, System.SR.CaptureGroupNameInvalid);
781 }
782 }
783 }
784 if ((num != -1 || num2 != -1) && CharsRight() > 0 && RightCharMoveRight() == c)
785 {
786 return new RegexNode(28, _options, num, num2);
787 }
788 break;
789 }
790 if (c == '\'')
791 {
792 break;
793 }
794 _options |= RegexOptions.RightToLeft;
795 type = 30;
796 }
797 else
798 {
799 if (c == '\'')
800 {
801 break;
802 }
803 _options |= RegexOptions.RightToLeft;
804 type = 31;
805 }
806 goto IL_0501;
807 }
808 case '(':
809 {
810 int num3 = Textpos();
811 if (CharsRight() > 0)
812 {
813 char c2 = RightChar();
814 if (c2 >= '0' && c2 <= '9')
815 {
816 int num4 = ScanDecimal();
817 if (CharsRight() > 0 && RightCharMoveRight() == ')')
818 {
819 if (IsCaptureSlot(num4))
820 {
821 return new RegexNode(33, _options, num4);
822 }
823 throw MakeException(RegexParseError.AlternationHasUndefinedReference, System.SR.Format(System.SR.AlternationHasUndefinedReference, num4.ToString()));
824 }
825 throw MakeException(RegexParseError.AlternationHasMalformedReference, System.SR.Format(System.SR.AlternationHasMalformedReference, num4.ToString()));
826 }
828 {
829 string capname2 = ScanCapname();
830 if (IsCaptureName(capname2) && CharsRight() > 0 && RightCharMoveRight() == ')')
831 {
833 }
834 }
835 }
836 type = 34;
837 Textto(num3 - 1);
838 _ignoreNextParen = true;
839 int num5 = CharsRight();
840 if (num5 >= 3 && RightChar(1) == '?')
841 {
842 char c4 = RightChar(2);
843 switch (c4)
844 {
845 case '#':
846 throw MakeException(RegexParseError.AlternationHasComment, System.SR.AlternationHasComment);
847 case '\'':
848 throw MakeException(RegexParseError.AlternationHasNamedCapture, System.SR.AlternationHasNamedCapture);
849 }
850 if (num5 >= 4 && c4 == '<' && RightChar(3) != '!' && RightChar(3) != '=')
851 {
852 throw MakeException(RegexParseError.AlternationHasNamedCapture, System.SR.AlternationHasNamedCapture);
853 }
854 }
855 goto IL_0501;
856 }
857 default:
858 {
859 MoveLeft();
860 type = 29;
861 if (_group.Type != 34)
862 {
863 ScanOptions();
864 }
865 if (CharsRight() == 0)
866 {
867 break;
868 }
869 char c2;
870 if ((c2 = RightCharMoveRight()) == ')')
871 {
872 return null;
873 }
874 if (c2 != ':')
875 {
876 break;
877 }
878 goto IL_0501;
879 }
880 IL_0501:
881 return new RegexNode(type, _options);
882 }
883 }
884 throw MakeException(RegexParseError.InvalidGroupingConstruct, System.SR.InvalidGroupingConstruct);
885 }
886
887 private void ScanBlank()
888 {
889 if (UseOptionX())
890 {
891 while (true)
892 {
893 if (CharsRight() > 0 && IsSpace(RightChar()))
894 {
895 MoveRight();
896 continue;
897 }
898 if (CharsRight() == 0)
899 {
900 break;
901 }
902 if (RightChar() == '#')
903 {
904 while (CharsRight() > 0 && RightChar() != '\n')
905 {
906 MoveRight();
907 }
908 continue;
909 }
910 if (CharsRight() >= 3 && RightChar(2) == '#' && RightChar(1) == '?' && RightChar() == '(')
911 {
912 while (CharsRight() > 0 && RightChar() != ')')
913 {
914 MoveRight();
915 }
916 if (CharsRight() == 0)
917 {
918 throw MakeException(RegexParseError.UnterminatedComment, System.SR.UnterminatedComment);
919 }
920 MoveRight();
921 continue;
922 }
923 break;
924 }
925 return;
926 }
927 while (true)
928 {
929 if (CharsRight() < 3 || RightChar(2) != '#' || RightChar(1) != '?' || RightChar() != '(')
930 {
931 return;
932 }
933 while (CharsRight() > 0 && RightChar() != ')')
934 {
935 MoveRight();
936 }
937 if (CharsRight() == 0)
938 {
939 break;
940 }
941 MoveRight();
942 }
943 throw MakeException(RegexParseError.UnterminatedComment, System.SR.UnterminatedComment);
944 }
945
947 {
948 char c;
949 switch (c = RightChar())
950 {
951 case 'A':
952 case 'B':
953 case 'G':
954 case 'Z':
955 case 'b':
956 case 'z':
957 MoveRight();
958 if (!scanOnly)
959 {
960 return new RegexNode(TypeFromCode(c), _options);
961 }
962 return null;
963 case 'w':
964 MoveRight();
965 if (!scanOnly)
966 {
967 return new RegexNode(11, _options, UseOptionE() ? "\0\n\00:A[_`a{İı" : "\0\0\n\0\u0002\u0004\u0005\u0003\u0001\u0006\t\u0013\0");
968 }
969 return null;
970 case 'W':
971 MoveRight();
972 if (!scanOnly)
973 {
974 return new RegexNode(11, _options, UseOptionE() ? "\u0001\n\00:A[_`a{İı" : "\u0001\0\n\0\u0002\u0004\u0005\u0003\u0001\u0006\t\u0013\0");
975 }
976 return null;
977 case 's':
978 MoveRight();
979 if (!scanOnly)
980 {
981 return new RegexNode(11, _options, UseOptionE() ? "\0\u0004\0\t\u000e !" : "\0\0\u0001d");
982 }
983 return null;
984 case 'S':
985 MoveRight();
986 if (!scanOnly)
987 {
988 return new RegexNode(11, _options, UseOptionE() ? "\u0001\u0004\0\t\u000e !" : "\u0001\0\u0001d");
989 }
990 return null;
991 case 'd':
992 MoveRight();
993 if (!scanOnly)
994 {
995 return new RegexNode(11, _options, UseOptionE() ? "\0\u0002\00:" : "\0\0\u0001\t");
996 }
997 return null;
998 case 'D':
999 MoveRight();
1000 if (!scanOnly)
1001 {
1002 return new RegexNode(11, _options, UseOptionE() ? "\u0001\u0002\00:" : "\0\0\u0001\ufff7");
1003 }
1004 return null;
1005 case 'P':
1006 case 'p':
1007 {
1008 MoveRight();
1009 if (scanOnly)
1010 {
1011 return null;
1012 }
1014 regexCharClass.AddCategoryFromName(ParseProperty(), c != 'p', UseOptionI(), _pattern, _currentPos);
1015 if (UseOptionI())
1016 {
1017 regexCharClass.AddLowercase(_culture);
1018 }
1019 return new RegexNode(11, _options, regexCharClass.ToStringClass());
1020 }
1021 default:
1023 }
1024 }
1025
1027 {
1028 if (CharsRight() == 0)
1029 {
1030 throw MakeException(RegexParseError.UnescapedEndingBackslash, System.SR.UnescapedEndingBackslash);
1031 }
1032 int pos = Textpos();
1033 char c = '\0';
1034 bool flag = false;
1035 char c2 = RightChar();
1036 switch (c2)
1037 {
1038 case 'k':
1039 if (CharsRight() >= 2)
1040 {
1041 MoveRight();
1043 if (c2 == '<' || c2 == '\'')
1044 {
1045 flag = true;
1046 c = ((c2 == '\'') ? '\'' : '>');
1047 }
1048 }
1049 if (!flag || CharsRight() <= 0)
1050 {
1051 throw MakeException(RegexParseError.MalformedNamedReference, System.SR.MalformedNamedReference);
1052 }
1053 c2 = RightChar();
1054 break;
1055 case '\'':
1056 case '<':
1057 if (CharsRight() > 1)
1058 {
1059 flag = true;
1060 c = ((c2 == '\'') ? '\'' : '>');
1061 MoveRight();
1062 c2 = RightChar();
1063 }
1064 break;
1065 }
1066 if (flag && c2 >= '0' && c2 <= '9')
1067 {
1068 int num = ScanDecimal();
1069 if (CharsRight() > 0 && RightCharMoveRight() == c)
1070 {
1071 if (!scanOnly)
1072 {
1073 if (!IsCaptureSlot(num))
1074 {
1075 throw MakeException(RegexParseError.UndefinedNumberedReference, System.SR.Format(System.SR.UndefinedNumberedReference, num.ToString()));
1076 }
1077 return new RegexNode(13, _options, num);
1078 }
1079 return null;
1080 }
1081 }
1082 else if (!flag && c2 >= '1' && c2 <= '9')
1083 {
1084 if (UseOptionE())
1085 {
1086 int num2 = -1;
1087 int num3 = c2 - 48;
1088 int num4 = Textpos() - 1;
1089 while (num3 <= _captop)
1090 {
1091 if (IsCaptureSlot(num3) && (_caps == null || (int)_caps[num3] < num4))
1092 {
1093 num2 = num3;
1094 }
1095 MoveRight();
1096 if (CharsRight() == 0 || (c2 = RightChar()) < '0' || c2 > '9')
1097 {
1098 break;
1099 }
1100 num3 = num3 * 10 + (c2 - 48);
1101 }
1102 if (num2 >= 0)
1103 {
1104 if (!scanOnly)
1105 {
1106 return new RegexNode(13, _options, num2);
1107 }
1108 return null;
1109 }
1110 }
1111 else
1112 {
1113 int num5 = ScanDecimal();
1114 if (scanOnly)
1115 {
1116 return null;
1117 }
1118 if (IsCaptureSlot(num5))
1119 {
1120 return new RegexNode(13, _options, num5);
1121 }
1122 if (num5 <= 9)
1123 {
1124 throw MakeException(RegexParseError.UndefinedNumberedReference, System.SR.Format(System.SR.UndefinedNumberedReference, num5.ToString()));
1125 }
1126 }
1127 }
1128 else if (flag && RegexCharClass.IsWordChar(c2))
1129 {
1130 string text = ScanCapname();
1131 if (CharsRight() > 0 && RightCharMoveRight() == c)
1132 {
1133 if (!scanOnly)
1134 {
1135 if (!IsCaptureName(text))
1136 {
1138 }
1139 return new RegexNode(13, _options, CaptureSlotFromName(text));
1140 }
1141 return null;
1142 }
1143 }
1144 Textto(pos);
1145 c2 = ScanCharEscape();
1146 if (UseOptionI())
1147 {
1148 c2 = _culture.TextInfo.ToLower(c2);
1149 }
1150 if (!scanOnly)
1151 {
1152 return new RegexNode(9, _options, c2);
1153 }
1154 return null;
1155 }
1156
1158 {
1159 if (CharsRight() == 0)
1160 {
1161 return new RegexNode(9, _options, '$');
1162 }
1163 char c = RightChar();
1164 int num = Textpos();
1165 int pos = num;
1166 bool flag;
1167 if (c == '{' && CharsRight() > 1)
1168 {
1169 flag = true;
1170 MoveRight();
1171 c = RightChar();
1172 }
1173 else
1174 {
1175 flag = false;
1176 }
1177 if (c >= '0' && c <= '9')
1178 {
1179 if (!flag && UseOptionE())
1180 {
1181 int num2 = -1;
1182 int num3 = c - 48;
1183 MoveRight();
1184 if (IsCaptureSlot(num3))
1185 {
1186 num2 = num3;
1187 pos = Textpos();
1188 }
1189 while (CharsRight() > 0 && (c = RightChar()) >= '0' && c <= '9')
1190 {
1191 int num4 = c - 48;
1192 if (num3 > 214748364 || (num3 == 214748364 && num4 > 7))
1193 {
1194 throw MakeException(RegexParseError.QuantifierOrCaptureGroupOutOfRange, System.SR.QuantifierOrCaptureGroupOutOfRange);
1195 }
1196 num3 = num3 * 10 + num4;
1197 MoveRight();
1198 if (IsCaptureSlot(num3))
1199 {
1200 num2 = num3;
1201 pos = Textpos();
1202 }
1203 }
1204 Textto(pos);
1205 if (num2 >= 0)
1206 {
1207 return new RegexNode(13, _options, num2);
1208 }
1209 }
1210 else
1211 {
1212 int num5 = ScanDecimal();
1213 if ((!flag || (CharsRight() > 0 && RightCharMoveRight() == '}')) && IsCaptureSlot(num5))
1214 {
1215 return new RegexNode(13, _options, num5);
1216 }
1217 }
1218 }
1219 else if (flag && RegexCharClass.IsWordChar(c))
1220 {
1221 string capname = ScanCapname();
1222 if (CharsRight() > 0 && RightCharMoveRight() == '}' && IsCaptureName(capname))
1223 {
1225 }
1226 }
1227 else if (!flag)
1228 {
1229 int num6 = 1;
1230 switch (c)
1231 {
1232 case '$':
1233 MoveRight();
1234 return new RegexNode(9, _options, '$');
1235 case '&':
1236 num6 = 0;
1237 break;
1238 case '`':
1239 num6 = -1;
1240 break;
1241 case '\'':
1242 num6 = -2;
1243 break;
1244 case '+':
1245 num6 = -3;
1246 break;
1247 case '_':
1248 num6 = -4;
1249 break;
1250 }
1251 if (num6 != 1)
1252 {
1253 MoveRight();
1254 return new RegexNode(13, _options, num6);
1255 }
1256 }
1257 Textto(num);
1258 return new RegexNode(9, _options, '$');
1259 }
1260
1261 private string ScanCapname()
1262 {
1263 int num = Textpos();
1264 while (CharsRight() > 0)
1265 {
1267 {
1268 MoveLeft();
1269 break;
1270 }
1271 }
1272 return _pattern.Substring(num, Textpos() - num);
1273 }
1274
1275 private char ScanOctal()
1276 {
1277 int num = 3;
1278 if (num > CharsRight())
1279 {
1280 num = CharsRight();
1281 }
1282 int num2 = 0;
1283 int num3;
1284 while (num > 0 && (uint)(num3 = RightChar() - 48) <= 7u)
1285 {
1286 MoveRight();
1287 num2 = num2 * 8 + num3;
1288 if (UseOptionE() && num2 >= 32)
1289 {
1290 break;
1291 }
1292 num--;
1293 }
1294 num2 &= 0xFF;
1295 return (char)num2;
1296 }
1297
1298 private int ScanDecimal()
1299 {
1300 int num = 0;
1301 int num2;
1302 while (CharsRight() > 0 && (uint)(num2 = (ushort)(RightChar() - 48)) <= 9u)
1303 {
1304 MoveRight();
1305 if (num > 214748364 || (num == 214748364 && num2 > 7))
1306 {
1307 throw MakeException(RegexParseError.QuantifierOrCaptureGroupOutOfRange, System.SR.QuantifierOrCaptureGroupOutOfRange);
1308 }
1309 num = num * 10 + num2;
1310 }
1311 return num;
1312 }
1313
1314 private char ScanHex(int c)
1315 {
1316 int num = 0;
1317 if (CharsRight() >= c)
1318 {
1319 int num2;
1320 while (c > 0 && (num2 = HexDigit(RightCharMoveRight())) >= 0)
1321 {
1322 num = num * 16 + num2;
1323 c--;
1324 }
1325 }
1326 if (c > 0)
1327 {
1328 throw MakeException(RegexParseError.InsufficientOrInvalidHexDigits, System.SR.InsufficientOrInvalidHexDigits);
1329 }
1330 return (char)num;
1331 }
1332
1333 private static int HexDigit(char ch)
1334 {
1335 int result;
1336 if ((uint)(result = ch - 48) <= 9u)
1337 {
1338 return result;
1339 }
1340 if ((uint)(result = ch - 97) <= 5u)
1341 {
1342 return result + 10;
1343 }
1344 if ((uint)(result = ch - 65) <= 5u)
1345 {
1346 return result + 10;
1347 }
1348 return -1;
1349 }
1350
1351 private char ScanControl()
1352 {
1353 if (CharsRight() == 0)
1354 {
1355 throw MakeException(RegexParseError.MissingControlCharacter, System.SR.MissingControlCharacter);
1356 }
1357 char c = RightCharMoveRight();
1358 if ((uint)(c - 97) <= 25u)
1359 {
1360 c = (char)(c - 32);
1361 }
1362 if ((c = (char)(c - 64)) < ' ')
1363 {
1364 return c;
1365 }
1366 throw MakeException(RegexParseError.UnrecognizedControlCharacter, System.SR.UnrecognizedControlCharacter);
1367 }
1368
1370 {
1371 if (options != RegexOptions.RightToLeft && options != RegexOptions.CultureInvariant)
1372 {
1373 return options == RegexOptions.ECMAScript;
1374 }
1375 return true;
1376 }
1377
1378 private void ScanOptions()
1379 {
1380 bool flag = false;
1381 while (CharsRight() > 0)
1382 {
1383 char c = RightChar();
1384 switch (c)
1385 {
1386 case '-':
1387 flag = true;
1388 break;
1389 case '+':
1390 flag = false;
1391 break;
1392 default:
1393 {
1396 {
1397 return;
1398 }
1399 if (flag)
1400 {
1402 }
1403 else
1404 {
1406 }
1407 break;
1408 }
1409 }
1410 MoveRight();
1411 }
1412 }
1413
1414 private char ScanCharEscape()
1415 {
1416 char c = RightCharMoveRight();
1417 if (c >= '0' && c <= '7')
1418 {
1419 MoveLeft();
1420 return ScanOctal();
1421 }
1422 switch (c)
1423 {
1424 case 'x':
1425 return ScanHex(2);
1426 case 'u':
1427 return ScanHex(4);
1428 case 'a':
1429 return '\a';
1430 case 'b':
1431 return '\b';
1432 case 'e':
1433 return '\u001b';
1434 case 'f':
1435 return '\f';
1436 case 'n':
1437 return '\n';
1438 case 'r':
1439 return '\r';
1440 case 't':
1441 return '\t';
1442 case 'v':
1443 return '\v';
1444 case 'c':
1445 return ScanControl();
1446 default:
1448 {
1450 }
1451 return c;
1452 }
1453 }
1454
1455 private string ParseProperty()
1456 {
1457 if (CharsRight() < 3)
1458 {
1459 throw MakeException(RegexParseError.InvalidUnicodePropertyEscape, System.SR.InvalidUnicodePropertyEscape);
1460 }
1461 char c = RightCharMoveRight();
1462 if (c != '{')
1463 {
1464 throw MakeException(RegexParseError.MalformedUnicodePropertyEscape, System.SR.MalformedUnicodePropertyEscape);
1465 }
1466 int num = Textpos();
1467 while (CharsRight() > 0)
1468 {
1469 c = RightCharMoveRight();
1470 if (!RegexCharClass.IsWordChar(c) && c != '-')
1471 {
1472 MoveLeft();
1473 break;
1474 }
1475 }
1476 string result = _pattern.Substring(num, Textpos() - num);
1477 if (CharsRight() == 0 || RightCharMoveRight() != '}')
1478 {
1479 throw MakeException(RegexParseError.InvalidUnicodePropertyEscape, System.SR.InvalidUnicodePropertyEscape);
1480 }
1481 return result;
1482 }
1483
1484 private int TypeFromCode(char ch)
1485 {
1486 return ch switch
1487 {
1488 'b' => UseOptionE() ? 41 : 16,
1489 'B' => UseOptionE() ? 42 : 17,
1490 'A' => 18,
1491 'G' => 19,
1492 'Z' => 20,
1493 'z' => 21,
1494 _ => 22,
1495 };
1496 }
1497
1498 private static RegexOptions OptionFromCode(char ch)
1499 {
1500 if ((uint)(ch - 65) <= 25u)
1501 {
1502 ch = (char)(ch + 32);
1503 }
1504 return ch switch
1505 {
1506 'i' => RegexOptions.IgnoreCase,
1507 'r' => RegexOptions.RightToLeft,
1508 'm' => RegexOptions.Multiline,
1509 'n' => RegexOptions.ExplicitCapture,
1510 's' => RegexOptions.Singleline,
1511 'x' => RegexOptions.IgnorePatternWhitespace,
1512 'e' => RegexOptions.ECMAScript,
1513 _ => RegexOptions.None,
1514 };
1515 }
1516
1517 private void CountCaptures()
1518 {
1519 NoteCaptureSlot(0, 0);
1520 _autocap = 1;
1521 while (CharsRight() > 0)
1522 {
1523 int pos = Textpos();
1524 switch (RightCharMoveRight())
1525 {
1526 case '\\':
1527 if (CharsRight() > 0)
1528 {
1529 ScanBackslash(scanOnly: true);
1530 }
1531 break;
1532 case '#':
1533 if (UseOptionX())
1534 {
1535 MoveLeft();
1536 ScanBlank();
1537 }
1538 break;
1539 case '[':
1540 ScanCharClass(caseInsensitive: false, scanOnly: true);
1541 break;
1542 case ')':
1543 if (!EmptyOptionsStack())
1544 {
1545 PopOptions();
1546 }
1547 break;
1548 case '(':
1549 if (CharsRight() >= 2 && RightChar(1) == '#' && RightChar() == '?')
1550 {
1551 MoveLeft();
1552 ScanBlank();
1553 }
1554 else
1555 {
1556 PushOptions();
1557 if (CharsRight() > 0 && RightChar() == '?')
1558 {
1559 MoveRight();
1560 if (CharsRight() > 1 && (RightChar() == '<' || RightChar() == '\''))
1561 {
1562 MoveRight();
1563 char c = RightChar();
1564 if (c != '0' && RegexCharClass.IsWordChar(c))
1565 {
1566 if ((uint)(c - 49) <= 8u)
1567 {
1569 }
1570 else
1571 {
1573 }
1574 }
1575 }
1576 else
1577 {
1578 ScanOptions();
1579 if (CharsRight() > 0)
1580 {
1581 if (RightChar() == ')')
1582 {
1583 MoveRight();
1585 }
1586 else if (RightChar() == '(')
1587 {
1588 _ignoreNextParen = true;
1589 break;
1590 }
1591 }
1592 }
1593 }
1594 else if (!UseOptionN() && !_ignoreNextParen)
1595 {
1596 NoteCaptureSlot(_autocap++, pos);
1597 }
1598 }
1599 _ignoreNextParen = false;
1600 break;
1601 }
1602 }
1604 }
1605
1606 private void NoteCaptureSlot(int i, int pos)
1607 {
1608 object key = i;
1609 if (!_caps.ContainsKey(key))
1610 {
1611 _caps.Add(key, pos);
1612 _capcount++;
1613 if (_captop <= i)
1614 {
1615 _captop = ((i == int.MaxValue) ? i : (i + 1));
1616 }
1617 }
1618 }
1619
1620 private void NoteCaptureName(string name, int pos)
1621 {
1622 if (_capnames == null)
1623 {
1624 _capnames = new Hashtable();
1625 _capnamelist = new List<string>();
1626 }
1628 {
1629 _capnames.Add(name, pos);
1631 }
1632 }
1633
1634 private void AssignNameSlots()
1635 {
1636 if (_capnames != null)
1637 {
1638 for (int i = 0; i < _capnamelist.Count; i++)
1639 {
1640 while (IsCaptureSlot(_autocap))
1641 {
1642 _autocap++;
1643 }
1644 string key = _capnamelist[i];
1645 int pos = (int)_capnames[key];
1648 _autocap++;
1649 }
1650 }
1651 if (_capcount < _captop)
1652 {
1653 _capnumlist = new int[_capcount];
1654 int num = 0;
1656 while (enumerator.MoveNext())
1657 {
1658 _capnumlist[num++] = (int)enumerator.Key;
1659 }
1661 }
1662 if (_capnames == null && _capnumlist == null)
1663 {
1664 return;
1665 }
1666 int num2 = 0;
1668 int num3;
1669 if (_capnames == null)
1670 {
1671 list = null;
1672 _capnames = new Hashtable();
1673 _capnamelist = new List<string>();
1674 num3 = -1;
1675 }
1676 else
1677 {
1679 _capnamelist = new List<string>();
1680 num3 = (int)_capnames[list[0]];
1681 }
1682 for (int j = 0; j < _capcount; j++)
1683 {
1684 int num4 = ((_capnumlist == null) ? j : _capnumlist[j]);
1685 if (num3 == num4)
1686 {
1688 num3 = ((num2 == list.Count) ? (-1) : ((int)_capnames[list[num2]]));
1689 }
1690 else
1691 {
1692 string text = num4.ToString(_culture);
1694 _capnames[text] = num4;
1695 }
1696 }
1697 }
1698
1699 private int CaptureSlotFromName(string capname)
1700 {
1701 return (int)_capnames[capname];
1702 }
1703
1704 private bool IsCaptureSlot(int i)
1705 {
1706 if (_caps != null)
1707 {
1708 return _caps.ContainsKey(i);
1709 }
1710 if (i >= 0)
1711 {
1712 return i < _capsize;
1713 }
1714 return false;
1715 }
1716
1717 private bool IsCaptureName(string capname)
1718 {
1719 if (_capnames != null)
1720 {
1722 }
1723 return false;
1724 }
1725
1726 private bool UseOptionN()
1727 {
1728 return (_options & RegexOptions.ExplicitCapture) != 0;
1729 }
1730
1731 private bool UseOptionI()
1732 {
1733 return (_options & RegexOptions.IgnoreCase) != 0;
1734 }
1735
1736 private bool UseOptionM()
1737 {
1738 return (_options & RegexOptions.Multiline) != 0;
1739 }
1740
1741 private bool UseOptionS()
1742 {
1743 return (_options & RegexOptions.Singleline) != 0;
1744 }
1745
1746 private bool UseOptionX()
1747 {
1748 return (_options & RegexOptions.IgnorePatternWhitespace) != 0;
1749 }
1750
1751 private bool UseOptionE()
1752 {
1753 return (_options & RegexOptions.ECMAScript) != 0;
1754 }
1755
1756 private static bool IsSpecial(char ch)
1757 {
1758 if (ch <= '|')
1759 {
1760 return Category[ch] >= 4;
1761 }
1762 return false;
1763 }
1764
1765 private static bool IsStopperX(char ch)
1766 {
1767 if (ch <= '|')
1768 {
1769 return Category[ch] >= 2;
1770 }
1771 return false;
1772 }
1773
1774 private static bool IsQuantifier(char ch)
1775 {
1776 if (ch <= '{')
1777 {
1778 return Category[ch] >= 5;
1779 }
1780 return false;
1781 }
1782
1783 private bool IsTrueQuantifier()
1784 {
1785 int num = Textpos();
1786 char c = CharAt(num);
1787 if (c != '{')
1788 {
1789 if (c <= '{')
1790 {
1791 return Category[c] >= 5;
1792 }
1793 return false;
1794 }
1795 int num2 = num;
1796 int num3 = CharsRight();
1797 while (--num3 > 0 && (uint)((c = CharAt(++num2)) - 48) <= 9u)
1798 {
1799 }
1800 if (num3 == 0 || num2 - num == 1)
1801 {
1802 return false;
1803 }
1804 switch (c)
1805 {
1806 case '}':
1807 return true;
1808 default:
1809 return false;
1810 case ',':
1811 break;
1812 }
1813 while (--num3 > 0 && (uint)((c = CharAt(++num2)) - 48) <= 9u)
1814 {
1815 }
1816 if (num3 > 0)
1817 {
1818 return c == '}';
1819 }
1820 return false;
1821 }
1822
1823 private static bool IsSpace(char ch)
1824 {
1825 if (ch <= ' ')
1826 {
1827 return Category[ch] == 2;
1828 }
1829 return false;
1830 }
1831
1832 private static bool IsMetachar(char ch)
1833 {
1834 if (ch <= '|')
1835 {
1836 return Category[ch] >= 1;
1837 }
1838 return false;
1839 }
1840
1841 private void AddConcatenate(int pos, int cch, bool isReplacement)
1842 {
1843 if (cch == 0)
1844 {
1845 return;
1846 }
1848 if (cch > 1)
1849 {
1850 string str = ((UseOptionI() && !isReplacement) ? string.Create(cch, (_pattern, _culture, pos, cch), delegate(Span<char> span, (string _pattern, CultureInfo _culture, int pos, int cch) state)
1851 {
1852 state._pattern.AsSpan(state.pos, state.cch).ToLower(span, state._culture);
1853 }) : _pattern.Substring(pos, cch));
1854 newChild = new RegexNode(12, _options, str);
1855 }
1856 else
1857 {
1858 char c = _pattern[pos];
1859 if (UseOptionI() && !isReplacement)
1860 {
1861 c = _culture.TextInfo.ToLower(c);
1862 }
1863 newChild = new RegexNode(9, _options, c);
1864 }
1866 }
1867
1868 private void PushGroup()
1869 {
1870 _group.Next = _stack;
1871 _alternation.Next = _group;
1872 _concatenation.Next = _alternation;
1874 }
1875
1876 private void PopGroup()
1877 {
1881 _stack = _group.Next;
1882 if (_group.Type == 34 && _group.ChildCount() == 0)
1883 {
1884 if (_unit == null)
1885 {
1886 throw MakeException(RegexParseError.AlternationHasMalformedCondition, System.SR.AlternationHasMalformedCondition);
1887 }
1889 _unit = null;
1890 }
1891 }
1892
1893 private bool EmptyStack()
1894 {
1895 return _stack == null;
1896 }
1897
1899 {
1900 _group = openGroup;
1901 _alternation = new RegexNode(24, _options);
1903 }
1904
1905 private void AddAlternate()
1906 {
1907 if (_group.Type == 34 || _group.Type == 33)
1908 {
1910 }
1911 else
1912 {
1914 }
1916 }
1917
1918 private void AddConcatenate()
1919 {
1921 _unit = null;
1922 }
1923
1924 private void AddConcatenate(bool lazy, int min, int max)
1925 {
1927 _unit = null;
1928 }
1929
1930 private RegexNode Unit()
1931 {
1932 return _unit;
1933 }
1934
1935 private void AddUnitOne(char ch)
1936 {
1937 if (UseOptionI())
1938 {
1939 ch = _culture.TextInfo.ToLower(ch);
1940 }
1941 _unit = new RegexNode(9, _options, ch);
1942 }
1943
1944 private void AddUnitNotone(char ch)
1945 {
1946 if (UseOptionI())
1947 {
1948 ch = _culture.TextInfo.ToLower(ch);
1949 }
1950 _unit = new RegexNode(10, _options, ch);
1951 }
1952
1953 private void AddUnitSet(string cc)
1954 {
1955 _unit = new RegexNode(11, _options, cc);
1956 }
1957
1959 {
1960 _unit = node;
1961 }
1962
1963 private void AddUnitType(int type)
1964 {
1965 _unit = new RegexNode(type, _options);
1966 }
1967
1968 private void AddGroup()
1969 {
1970 if (_group.Type == 34 || _group.Type == 33)
1971 {
1973 if ((_group.Type == 33 && _group.ChildCount() > 2) || _group.ChildCount() > 3)
1974 {
1975 throw MakeException(RegexParseError.AlternationHasTooManyConditions, System.SR.AlternationHasTooManyConditions);
1976 }
1977 }
1978 else
1979 {
1982 }
1983 _unit = _group;
1984 }
1985
1986 private void PushOptions()
1987 {
1988 _optionsStack.Append((int)_options);
1989 }
1990
1991 private void PopOptions()
1992 {
1994 }
1995
1996 private bool EmptyOptionsStack()
1997 {
1998 return _optionsStack.Length == 0;
1999 }
2000
2001 private void PopKeepOptions()
2002 {
2003 _optionsStack.Length--;
2004 }
2005
2010
2011 private int Textpos()
2012 {
2013 return _currentPos;
2014 }
2015
2016 private void Textto(int pos)
2017 {
2018 _currentPos = pos;
2019 }
2020
2021 private char RightCharMoveRight()
2022 {
2023 return _pattern[_currentPos++];
2024 }
2025
2026 private void MoveRight()
2027 {
2028 _currentPos++;
2029 }
2030
2031 private void MoveRight(int i)
2032 {
2033 _currentPos += i;
2034 }
2035
2036 private void MoveLeft()
2037 {
2038 _currentPos--;
2039 }
2040
2041 private char CharAt(int i)
2042 {
2043 return _pattern[i];
2044 }
2045
2046 private char RightChar()
2047 {
2048 return _pattern[_currentPos];
2049 }
2050
2051 private char RightChar(int i)
2052 {
2053 return _pattern[_currentPos + i];
2054 }
2055
2056 private int CharsRight()
2057 {
2058 return _pattern.Length - _currentPos;
2059 }
2060}
static void Sort(Array array)
Definition Array.cs:2329
void AddRange(IEnumerable< KeyValuePair< TKey, TValue > > collection)
IEnumerator IEnumerable. GetEnumerator()
Definition Hashtable.cs:899
virtual bool ContainsKey(object key)
Definition Hashtable.cs:724
virtual void Add(object key, object? value)
Definition Hashtable.cs:676
static CultureInfo CurrentCulture
static CultureInfo InvariantCulture
static string AlternationHasMalformedReference
Definition SR.cs:52
static string InsufficientOrInvalidHexDigits
Definition SR.cs:82
static string InvalidUnicodePropertyEscape
Definition SR.cs:40
static string UnrecognizedEscape
Definition SR.cs:100
static string ShorthandClassInCharacterRange
Definition SR.cs:20
static string AlternationHasUndefinedReference
Definition SR.cs:92
static string AlternationHasMalformedCondition
Definition SR.cs:32
static string Format(string resourceFormat, object p1)
Definition SR.cs:118
static string QuantifierOrCaptureGroupOutOfRange
Definition SR.cs:24
static string MalformedNamedReference
Definition SR.cs:50
static string UnterminatedBracket
Definition SR.cs:104
static string QuantifierAfterNothing
Definition SR.cs:72
static string UndefinedNumberedReference
Definition SR.cs:88
static string NestedQuantifiersNotParenthesized
Definition SR.cs:60
static string UnterminatedComment
Definition SR.cs:106
static string CaptureGroupOfZero
Definition SR.cs:26
static string ExclusionGroupNotLast
Definition SR.cs:80
static string UnrecognizedControlCharacter
Definition SR.cs:98
static string InsufficientOpeningParentheses
Definition SR.cs:86
static string MissingControlCharacter
Definition SR.cs:58
static string AlternationHasComment
Definition SR.cs:16
static string InternalError_ScanRegex
Definition SR.cs:42
static string ReversedCharacterRange
Definition SR.cs:78
static string MakeException
Definition SR.cs:56
static string CaptureGroupNameInvalid
Definition SR.cs:44
static string MalformedUnicodePropertyEscape
Definition SR.cs:54
static string InsufficientClosingParentheses
Definition SR.cs:64
static string UnescapedEndingBackslash
Definition SR.cs:36
static string AlternationHasTooManyConditions
Definition SR.cs:84
static string AlternationHasNamedCapture
Definition SR.cs:14
static string ReversedQuantifierRange
Definition SR.cs:38
static string InvalidGroupingConstruct
Definition SR.cs:102
static string UndefinedNamedReference
Definition SR.cs:90
Definition SR.cs:7
RegexNode MakeQuantifier(bool lazy, int min, int max)
void AddChild(RegexNode newChild)
static RegexReplacement ParseReplacement(string pattern, RegexOptions options, Hashtable caps, int capsize, Hashtable capnames)
static ReadOnlySpan< byte > Category
RegexParser(string pattern, RegexOptions options, CultureInfo culture, Hashtable caps, int capsize, Hashtable capnames, Span< int > optionSpan)
void AddConcatenate(bool lazy, int min, int max)
static RegexOptions OptionFromCode(char ch)
RegexParseException MakeException(RegexParseError error, string message)
static string UnescapeImpl(string input, int i)
static string EscapeImpl(string input, int i)
RegexNode ScanBasicBackslash(bool scanOnly)
static RegexTree Parse(string pattern, RegexOptions options, CultureInfo culture)
void AddConcatenate(int pos, int cch, bool isReplacement)
RegexParser(string pattern, RegexOptions options, CultureInfo culture, Span< int > optionSpan)
static string Escape(string input)
RegexCharClass ScanCharClass(bool caseInsensitive, bool scanOnly)
System.Collections.Generic.ValueListBuilder< int > _optionsStack
bool IsOnlyTopOption(RegexOptions options)
void NoteCaptureName(string name, int pos)
static string Unescape(string input)