1313 references to RegexNodeKind
System.Text.RegularExpressions (1313)
System\Text\RegularExpressions\RegexCompiler.cs (135)
513
if (RegexPrefixAnalyzer.FindTrailingAnchor(_regexTree.Root) ==
RegexNodeKind
.End &&
669
case
RegexNodeKind
.Bol:
748
case
RegexNodeKind
.End or
RegexNodeKind
.EndZ when _regexTree.FindOptimizations.MaxPossibleLength is int maxLength:
1269
Debug.Assert(target.LoopNode.Kind is
RegexNodeKind
.Setloop or
RegexNodeKind
.Setlazy or
RegexNodeKind
.Setloopatomic);
1452
Debug.Assert(node.Kind ==
RegexNodeKind
.Capture, "Every generated tree should begin with a capture node");
1462
case
RegexNodeKind
.Multi or
RegexNodeKind
.Notone or
RegexNodeKind
.One or
RegexNodeKind
.Set:
1468
int length = node.Kind ==
RegexNodeKind
.Multi ? node.Str!.Length : 1;
1668
Debug.Assert(node.Kind is
RegexNodeKind
.Alternate, $"Unexpected type: {node.Kind}");
2028
case
RegexNodeKind
.One:
2029
case
RegexNodeKind
.Set:
2034
case
RegexNodeKind
.Multi:
2040
case
RegexNodeKind
.Concatenate when child.Child(0) == startingLiteralNode && (startingLiteralNode.Kind is
RegexNodeKind
.One or
RegexNodeKind
.Set or
RegexNodeKind
.Multi):
2050
child.Child(0).Kind is
RegexNodeKind
.Multi ?
2052
new RegexNode(
RegexNodeKind
.Empty, child.Options));
2090
Debug.Assert(multi.Kind is
RegexNodeKind
.Multi, $"Expected a Multi node, got {multi.Kind}");
2092
new(
RegexNodeKind
.One, multi.Options, multi.Str[1]) :
2093
new(
RegexNodeKind
.Multi, multi.Options, multi.Str.Substring(1));
2100
Debug.Assert(node.Kind is
RegexNodeKind
.Backreference, $"Unexpected type: {node.Kind}");
2290
Debug.Assert(node.Kind is
RegexNodeKind
.BackreferenceConditional, $"Unexpected type: {node.Kind}");
2304
RegexNode? noBranch = node.Child(1) is { Kind: not
RegexNodeKind
.Empty } childNo ? childNo : null;
2449
Debug.Assert(node.Kind is
RegexNodeKind
.ExpressionConditional, $"Unexpected type: {node.Kind}");
2465
RegexNode? noBranch = node.Child(2) is { Kind: not
RegexNodeKind
.Empty } childNo ? childNo : null;
2642
Debug.Assert(node.Kind is
RegexNodeKind
.Capture, $"Unexpected type: {node.Kind}");
2768
Debug.Assert(node.Kind is
RegexNodeKind
.PositiveLookaround, $"Unexpected type: {node.Kind}");
2812
Debug.Assert(node.Kind is
RegexNodeKind
.NegativeLookaround, $"Unexpected type: {node.Kind}");
2963
case
RegexNodeKind
.Beginning:
2964
case
RegexNodeKind
.Start:
2965
case
RegexNodeKind
.Bol:
2966
case
RegexNodeKind
.Eol:
2967
case
RegexNodeKind
.End:
2968
case
RegexNodeKind
.EndZ:
2972
case
RegexNodeKind
.Boundary:
2973
case
RegexNodeKind
.NonBoundary:
2974
case
RegexNodeKind
.ECMABoundary:
2975
case
RegexNodeKind
.NonECMABoundary:
2979
case
RegexNodeKind
.Multi:
2983
case
RegexNodeKind
.One:
2984
case
RegexNodeKind
.Notone:
2985
case
RegexNodeKind
.Set:
2989
case
RegexNodeKind
.Oneloop:
2990
case
RegexNodeKind
.Notoneloop:
2991
case
RegexNodeKind
.Setloop:
2995
case
RegexNodeKind
.Onelazy:
2996
case
RegexNodeKind
.Notonelazy:
2997
case
RegexNodeKind
.Setlazy:
3001
case
RegexNodeKind
.Oneloopatomic:
3002
case
RegexNodeKind
.Notoneloopatomic:
3003
case
RegexNodeKind
.Setloopatomic:
3007
case
RegexNodeKind
.Loop:
3011
case
RegexNodeKind
.Lazyloop:
3015
case
RegexNodeKind
.Alternate:
3019
case
RegexNodeKind
.Concatenate:
3023
case
RegexNodeKind
.Atomic:
3027
case
RegexNodeKind
.Backreference:
3031
case
RegexNodeKind
.BackreferenceConditional:
3035
case
RegexNodeKind
.ExpressionConditional:
3039
case
RegexNodeKind
.Capture:
3043
case
RegexNodeKind
.PositiveLookaround:
3047
case
RegexNodeKind
.NegativeLookaround:
3051
case
RegexNodeKind
.Nothing:
3055
case
RegexNodeKind
.Empty:
3059
case
RegexNodeKind
.UpdateBumpalong:
3071
Debug.Assert(node.Kind is
RegexNodeKind
.Atomic or
RegexNodeKind
.PositiveLookaround or
RegexNodeKind
.NegativeLookaround or
RegexNodeKind
.ExpressionConditional, $"Unexpected type: {node.Kind}");
3072
Debug.Assert(node.Kind is
RegexNodeKind
.ExpressionConditional ? node.ChildCount() >= 1 : node.ChildCount() == 1, $"Unexpected number of children: {node.ChildCount()}");
3078
if (node.Kind is
RegexNodeKind
.Atomic && !analysis.MayBacktrack(child))
3115
Debug.Assert(node.Kind is
RegexNodeKind
.UpdateBumpalong, $"Unexpected type: {node.Kind}");
3135
Debug.Assert(node.Kind is
RegexNodeKind
.Concatenate, $"Unexpected type: {node.Kind}");
3193
if (next.Kind is not
RegexNodeKind
.UpdateBumpalong) // skip node types that don't have a semantic impact
3281
Debug.Assert(node.Kind is
RegexNodeKind
.Boundary or
RegexNodeKind
.NonBoundary or
RegexNodeKind
.ECMABoundary or
RegexNodeKind
.NonECMABoundary, $"Unexpected type: {node.Kind}");
3299
case
RegexNodeKind
.Boundary or
RegexNodeKind
.NonBoundary:
3313
if (node.Kind is
RegexNodeKind
.Boundary)
3326
if (node.Kind is
RegexNodeKind
.ECMABoundary)
3341
Debug.Assert(node.Kind is
RegexNodeKind
.Beginning or
RegexNodeKind
.Start or
RegexNodeKind
.Bol or
RegexNodeKind
.End or
RegexNodeKind
.EndZ or
RegexNodeKind
.Eol, $"Unexpected type: {node.Kind}");
3348
case
RegexNodeKind
.Beginning:
3349
case
RegexNodeKind
.Start:
3360
if (node.Kind ==
RegexNodeKind
.Beginning)
3372
case
RegexNodeKind
.Bol:
3403
case
RegexNodeKind
.End:
3420
case
RegexNodeKind
.EndZ:
3437
goto case
RegexNodeKind
.Eol;
3439
case
RegexNodeKind
.Eol:
3479
Debug.Assert(node.Kind is
RegexNodeKind
.Multi, $"Unexpected type: {node.Kind}");
3531
Debug.Assert(node.Kind is
RegexNodeKind
.Oneloop or
RegexNodeKind
.Notoneloop or
RegexNodeKind
.Setloop, $"Unexpected type: {node.Kind}");
3747
Debug.Assert(node.Kind is
RegexNodeKind
.Onelazy or
RegexNodeKind
.Notonelazy or
RegexNodeKind
.Setlazy, $"Unexpected type: {node.Kind}");
3848
node.Kind is
RegexNodeKind
.Notonelazy &&
3989
node.Kind is
RegexNodeKind
.Setlazy &&
4094
Debug.Assert(node.Kind is
RegexNodeKind
.Lazyloop, $"Unexpected type: {node.Kind}");
4605
Debug.Assert(node.Kind is
RegexNodeKind
.Oneloop or
RegexNodeKind
.Oneloopatomic or
RegexNodeKind
.Notoneloop or
RegexNodeKind
.Notoneloopatomic or
RegexNodeKind
.Setloop or
RegexNodeKind
.Setloopatomic, $"Unexpected type: {node.Kind}");
4852
Debug.Assert(node.Kind is
RegexNodeKind
.Oneloop or
RegexNodeKind
.Oneloopatomic or
RegexNodeKind
.Notoneloop or
RegexNodeKind
.Notoneloopatomic or
RegexNodeKind
.Setloop or
RegexNodeKind
.Setloopatomic, $"Unexpected type: {node.Kind}");
4941
Debug.Assert(node.Kind is
RegexNodeKind
.Loop or
RegexNodeKind
.Lazyloop, $"Unexpected type: {node.Kind}");
4979
Debug.Assert(node.Kind is
RegexNodeKind
.Loop or
RegexNodeKind
.Lazyloop, $"Unexpected type: {node.Kind}");
5377
if (node.Kind ==
RegexNodeKind
.Multi)
5410
if (node.Kind ==
RegexNodeKind
.Multi)
5603
if (root.Kind is
RegexNodeKind
.Multi or
RegexNodeKind
.One or
RegexNodeKind
.Notone or
RegexNodeKind
.Set)
5621
Ldc((root.Kind ==
RegexNodeKind
.Multi ? root.Str!.Length : 1) * (!rtl ? 1 : -1));
System\Text\RegularExpressions\RegexFindOptimizations.cs (23)
56
if (rightToLeft && LeadingAnchor ==
RegexNodeKind
.Bol)
59
LeadingAnchor =
RegexNodeKind
.Unknown;
61
if (LeadingAnchor is
RegexNodeKind
.Beginning or
RegexNodeKind
.Start or
RegexNodeKind
.EndZ or
RegexNodeKind
.End)
65
(
RegexNodeKind
.Beginning, false) => FindNextStartingPositionMode.LeadingAnchor_LeftToRight_Beginning,
66
(
RegexNodeKind
.Beginning, true) => FindNextStartingPositionMode.LeadingAnchor_RightToLeft_Beginning,
67
(
RegexNodeKind
.Start, false) => FindNextStartingPositionMode.LeadingAnchor_LeftToRight_Start,
68
(
RegexNodeKind
.Start, true) => FindNextStartingPositionMode.LeadingAnchor_RightToLeft_Start,
69
(
RegexNodeKind
.End, false) => FindNextStartingPositionMode.LeadingAnchor_LeftToRight_End,
70
(
RegexNodeKind
.End, true) => FindNextStartingPositionMode.LeadingAnchor_RightToLeft_End,
83
if (TrailingAnchor is
RegexNodeKind
.End or
RegexNodeKind
.EndZ &&
90
FindMode = TrailingAnchor ==
RegexNodeKind
.End ?
280
LeadingAnchor ==
RegexNodeKind
.Bol; // there's a leading BOL anchor we can otherwise search for
286
public
RegexNodeKind
LeadingAnchor { get; private set; }
289
public
RegexNodeKind
TrailingAnchor { get; }
409
Debug.Assert(LeadingAnchor !=
RegexNodeKind
.Bol, "BOL isn't enabled for RTL");
535
if (LeadingAnchor ==
RegexNodeKind
.Bol)
822
Debug.Assert(loopNode.Kind is
RegexNodeKind
.Setloop or
RegexNodeKind
.Setlazy or
RegexNodeKind
.Setloopatomic);
System\Text\RegularExpressions\RegexNode.cs (729)
23
public
RegexNodeKind
Kind { get; private set; }
26
/// <remarks>For a <see cref="
RegexNodeKind
.Multi"/>, this is the string from the expression. For an <see cref="IsSetFamily"/> node, this is the character class string from <see cref="RegexCharClass"/>.</remarks>
51
public RegexNode(
RegexNodeKind
kind, RegexOptions options)
57
public RegexNode(
RegexNodeKind
kind, RegexOptions options, char ch)
64
public RegexNode(
RegexNodeKind
kind, RegexOptions options, string str)
71
public RegexNode(
RegexNodeKind
kind, RegexOptions options, int m)
78
public RegexNode(
RegexNodeKind
kind, RegexOptions options, int m, int n)
89
Debug.Assert(Kind is
RegexNodeKind
.Onelazy or
RegexNodeKind
.Oneloop or
RegexNodeKind
.Oneloopatomic or
90
RegexNodeKind
.Notonelazy or
RegexNodeKind
.Notoneloop or
RegexNodeKind
.Notoneloopatomic or
91
RegexNodeKind
.Setlazy or
RegexNodeKind
.Setloop or
RegexNodeKind
.Setloopatomic);
121
return new RegexNode(
RegexNodeKind
.One, options & ~RegexOptions.IgnoreCase, ch);
127
return new RegexNode(
RegexNodeKind
.Set, options & ~RegexOptions.IgnoreCase, stringSet);
131
return new RegexNode(
RegexNodeKind
.One, options, ch);
138
Kind ==
RegexNodeKind
.Concatenate &&
150
private void MakeRep(
RegexNodeKind
kind, int min, int max)
152
Kind += kind -
RegexNodeKind
.One;
169
case
RegexNodeKind
.Oneloop or
RegexNodeKind
.Notoneloop or
RegexNodeKind
.Setloop:
172
Kind +=
RegexNodeKind
.Oneloopatomic -
RegexNodeKind
.Oneloop;
175
case
RegexNodeKind
.Onelazy or
RegexNodeKind
.Notonelazy or
RegexNodeKind
.Setlazy:
179
Kind +=
RegexNodeKind
.Oneloopatomic -
RegexNodeKind
.Onelazy;
189
Kind =
RegexNodeKind
.Empty;
193
else if (Kind ==
RegexNodeKind
.Oneloopatomic && N is >= 2 and <= MultiVsRepeaterLimit)
197
Kind =
RegexNodeKind
.Multi;
204
case
RegexNodeKind
.Loop:
205
if (Parent is not { Kind:
RegexNodeKind
.Atomic })
207
RegexNode loopAsChild = new(
RegexNodeKind
.Loop, Options, M, N);
208
Kind =
RegexNodeKind
.Atomic;
215
case
RegexNodeKind
.Lazyloop:
225
goto case
RegexNodeKind
.Loop;
228
Kind =
RegexNodeKind
.Empty;
243
Debug.Assert(Kind ==
RegexNodeKind
.Capture, "Every generated tree should begin with a capture node");
262
Debug.Assert(Kind !=
RegexNodeKind
.Group, "All Group nodes should have been removed.");
267
case
RegexNodeKind
.Group:
271
case
RegexNodeKind
.Beginning:
272
case
RegexNodeKind
.Bol:
273
case
RegexNodeKind
.Boundary:
274
case
RegexNodeKind
.ECMABoundary:
275
case
RegexNodeKind
.Empty:
276
case
RegexNodeKind
.End:
277
case
RegexNodeKind
.EndZ:
278
case
RegexNodeKind
.Eol:
279
case
RegexNodeKind
.Multi:
280
case
RegexNodeKind
.NonBoundary:
281
case
RegexNodeKind
.NonECMABoundary:
282
case
RegexNodeKind
.Nothing:
283
case
RegexNodeKind
.Notone:
284
case
RegexNodeKind
.Notonelazy:
285
case
RegexNodeKind
.Notoneloop:
286
case
RegexNodeKind
.Notoneloopatomic:
287
case
RegexNodeKind
.One:
288
case
RegexNodeKind
.Onelazy:
289
case
RegexNodeKind
.Oneloop:
290
case
RegexNodeKind
.Oneloopatomic:
291
case
RegexNodeKind
.Backreference:
292
case
RegexNodeKind
.Set:
293
case
RegexNodeKind
.Setlazy:
294
case
RegexNodeKind
.Setloop:
295
case
RegexNodeKind
.Setloopatomic:
296
case
RegexNodeKind
.Start:
297
case
RegexNodeKind
.UpdateBumpalong:
301
case
RegexNodeKind
.Atomic:
302
case
RegexNodeKind
.Capture:
303
case
RegexNodeKind
.Lazyloop:
304
case
RegexNodeKind
.Loop:
305
case
RegexNodeKind
.NegativeLookaround:
306
case
RegexNodeKind
.PositiveLookaround:
310
case
RegexNodeKind
.BackreferenceConditional:
314
case
RegexNodeKind
.ExpressionConditional:
318
case
RegexNodeKind
.Concatenate:
319
case
RegexNodeKind
.Alternate:
331
case
RegexNodeKind
.Multi:
336
case
RegexNodeKind
.Set:
337
case
RegexNodeKind
.Setloop:
338
case
RegexNodeKind
.Setloopatomic:
339
case
RegexNodeKind
.Setlazy:
351
case
RegexNodeKind
.Backreference:
372
Debug.Assert(rootNode.Kind ==
RegexNodeKind
.Capture);
415
case
RegexNodeKind
.Atomic:
419
case
RegexNodeKind
.Concatenate:
424
case
RegexNodeKind
.Oneloop or
RegexNodeKind
.Oneloopatomic or
RegexNodeKind
.Notoneloop or
RegexNodeKind
.Notoneloopatomic or
RegexNodeKind
.Setloop or
RegexNodeKind
.Setloopatomic when node.N == int.MaxValue:
425
case
RegexNodeKind
.Onelazy or
RegexNodeKind
.Notonelazy or
RegexNodeKind
.Setlazy when node.N == int.MaxValue && !atomicByAncestry:
426
if (node.Parent is { Kind:
RegexNodeKind
.Concatenate } parent)
428
parent.InsertChild(1, new RegexNode(
RegexNodeKind
.UpdateBumpalong, node.Options));
476
case
RegexNodeKind
.Oneloop or
RegexNodeKind
.Notoneloop or
RegexNodeKind
.Setloop:
477
case
RegexNodeKind
.Onelazy or
RegexNodeKind
.Notonelazy or
RegexNodeKind
.Setlazy:
483
case
RegexNodeKind
.Atomic:
484
case
RegexNodeKind
.PositiveLookaround:
485
case
RegexNodeKind
.NegativeLookaround:
495
case
RegexNodeKind
.Capture:
496
case
RegexNodeKind
.Concatenate when !rtl:
498
if ((existingChild.Kind is
RegexNodeKind
.Alternate or
RegexNodeKind
.BackreferenceConditional or
RegexNodeKind
.ExpressionConditional or
RegexNodeKind
.Loop or
RegexNodeKind
.Lazyloop) &&
499
node.Parent is not { Kind:
RegexNodeKind
.Atomic }) // validate grandparent isn't atomic
501
var atomic = new RegexNode(
RegexNodeKind
.Atomic, existingChild.Options);
511
case
RegexNodeKind
.Alternate:
512
case
RegexNodeKind
.BackreferenceConditional:
513
case
RegexNodeKind
.ExpressionConditional:
521
if (node.Kind !=
RegexNodeKind
.ExpressionConditional) // ReduceExpressionConditional will have already applied ending backtracking removal
536
case
RegexNodeKind
.Lazyloop:
537
case
RegexNodeKind
.Loop:
542
Debug.Assert(node.Kind is
RegexNodeKind
.Atomic or
RegexNodeKind
.Empty or
RegexNodeKind
.Loop or
RegexNodeKind
.Lazyloop);
544
if (node.Kind is
RegexNodeKind
.Atomic)
547
Debug.Assert(node.Kind is
RegexNodeKind
.Loop or
RegexNodeKind
.Lazyloop);
550
if (node.Kind is
RegexNodeKind
.Loop or
RegexNodeKind
.Lazyloop)
584
case
RegexNodeKind
.Backreference:
591
RegexNodeKind
.Alternate => ReduceAlternation(),
592
RegexNodeKind
.Atomic => ReduceAtomic(),
593
RegexNodeKind
.Concatenate => ReduceConcatenation(),
594
RegexNodeKind
.Group => ReduceGroup(),
595
RegexNodeKind
.Loop or
RegexNodeKind
.Lazyloop => ReduceLoops(),
596
RegexNodeKind
.PositiveLookaround or
RegexNodeKind
.NegativeLookaround => ReduceLookaround(),
597
RegexNodeKind
.Set or
RegexNodeKind
.Setloop or
RegexNodeKind
.Setloopatomic or
RegexNodeKind
.Setlazy => ReduceSet(),
598
RegexNodeKind
.ExpressionConditional => ReduceExpressionConditional(),
599
RegexNodeKind
.BackreferenceConditional => ReduceBackreferenceConditional(),
612
Debug.Assert(Kind is
RegexNodeKind
.Alternate or
RegexNodeKind
.Concatenate);
615
0 => new RegexNode(Kind ==
RegexNodeKind
.Alternate ?
RegexNodeKind
.Nothing :
RegexNodeKind
.Empty, Options),
629
Debug.Assert(Kind ==
RegexNodeKind
.Group);
632
while (u.Kind ==
RegexNodeKind
.Group)
657
Debug.Assert(Kind ==
RegexNodeKind
.Atomic);
662
while (child.Kind ==
RegexNodeKind
.Atomic)
672
case
RegexNodeKind
.Empty:
673
case
RegexNodeKind
.Nothing:
677
case
RegexNodeKind
.Oneloopatomic:
678
case
RegexNodeKind
.Notoneloopatomic:
679
case
RegexNodeKind
.Setloopatomic:
684
case
RegexNodeKind
.Oneloop:
685
case
RegexNodeKind
.Notoneloop:
686
case
RegexNodeKind
.Setloop:
687
case
RegexNodeKind
.Onelazy:
688
case
RegexNodeKind
.Notonelazy:
689
case
RegexNodeKind
.Setlazy:
695
case
RegexNodeKind
.Alternate:
704
if (branches[0].Kind ==
RegexNodeKind
.Empty)
706
return new RegexNode(
RegexNodeKind
.Empty, child.Options);
715
if (branches[i].Kind ==
RegexNodeKind
.Empty)
796
(child.Child(0).Kind is
RegexNodeKind
.Empty || child.Child(1).Kind is
RegexNodeKind
.Empty); // can be transformed into a ? or ??
811
return child.Kind ==
RegexNodeKind
.Empty ?
826
Debug.Assert(Kind is
RegexNodeKind
.Loop or
RegexNodeKind
.Lazyloop);
829
RegexNodeKind
kind = Kind;
842
if (kind ==
RegexNodeKind
.Loop)
846
case
RegexNodeKind
.Oneloop:
847
case
RegexNodeKind
.Oneloopatomic:
848
case
RegexNodeKind
.Notoneloop:
849
case
RegexNodeKind
.Notoneloopatomic:
850
case
RegexNodeKind
.Setloop:
851
case
RegexNodeKind
.Setloopatomic:
860
case
RegexNodeKind
.Onelazy:
861
case
RegexNodeKind
.Notonelazy:
862
case
RegexNodeKind
.Setlazy:
896
return new RegexNode(
RegexNodeKind
.Nothing, Options);
907
case
RegexNodeKind
.One:
908
case
RegexNodeKind
.Notone:
909
case
RegexNodeKind
.Set:
910
child.MakeRep(u.Kind ==
RegexNodeKind
.Lazyloop ?
RegexNodeKind
.Onelazy :
RegexNodeKind
.Oneloop, u.M, u.N);
914
case
RegexNodeKind
.Empty:
919
case
RegexNodeKind
.PositiveLookaround when ContainsKind(child, [
RegexNodeKind
.Capture]) is false:
920
case
RegexNodeKind
.NegativeLookaround or
921
RegexNodeKind
.Beginning or
RegexNodeKind
.Start or
922
RegexNodeKind
.Bol or
RegexNodeKind
.Eol or
923
RegexNodeKind
.End or
RegexNodeKind
.EndZ or
924
RegexNodeKind
.Boundary or
RegexNodeKind
.ECMABoundary or
925
RegexNodeKind
.NonBoundary or
RegexNodeKind
.NonECMABoundary:
935
u = u.M == 0 ? new RegexNode(
RegexNodeKind
.Empty, Options) : child;
958
Debug.Assert(Kind is
RegexNodeKind
.Set or
RegexNodeKind
.Setloop or
RegexNodeKind
.Setloopatomic or
RegexNodeKind
.Setlazy);
963
Kind =
RegexNodeKind
.Nothing;
971
Kind ==
RegexNodeKind
.Set ?
RegexNodeKind
.One :
972
Kind ==
RegexNodeKind
.Setloop ?
RegexNodeKind
.Oneloop :
973
Kind ==
RegexNodeKind
.Setloopatomic ?
RegexNodeKind
.Oneloopatomic :
974
RegexNodeKind
.Onelazy;
981
Kind ==
RegexNodeKind
.Set ?
RegexNodeKind
.Notone :
982
Kind ==
RegexNodeKind
.Setloop ?
RegexNodeKind
.Notoneloop :
983
Kind ==
RegexNodeKind
.Setloopatomic ?
RegexNodeKind
.Notoneloopatomic :
984
RegexNodeKind
.Notonelazy;
1018
Debug.Assert(Kind ==
RegexNodeKind
.Alternate);
1023
return new RegexNode(
RegexNodeKind
.Nothing, Options);
1031
if (node.Kind ==
RegexNodeKind
.Alternate)
1034
if (node.Kind ==
RegexNodeKind
.Alternate)
1037
if (node.Kind ==
RegexNodeKind
.Alternate)
1045
if (node.Kind is
RegexNodeKind
.Alternate && node.ChildCount() == 2)
1047
if (node.Child(1).Kind is
RegexNodeKind
.Empty)
1051
else if (node.Child(0).Kind is
RegexNodeKind
.Empty)
1088
if (at.Kind ==
RegexNodeKind
.Alternate)
1106
else if (at.Kind is
RegexNodeKind
.Set or
RegexNodeKind
.One)
1111
if (at.Kind ==
RegexNodeKind
.Set)
1135
if (prev.Kind ==
RegexNodeKind
.One)
1145
if (at.Kind ==
RegexNodeKind
.One)
1155
prev.Kind =
RegexNodeKind
.Set;
1162
else if (at.Kind ==
RegexNodeKind
.Nothing)
1186
Debug.Assert(alternation.Kind ==
RegexNodeKind
.Alternate);
1199
if (child.Kind !=
RegexNodeKind
.Concatenate || child.ChildCount() < 2)
1216
case
RegexNodeKind
.One or
RegexNodeKind
.Notone or
RegexNodeKind
.Set:
1217
case
RegexNodeKind
.Oneloopatomic or
RegexNodeKind
.Notoneloopatomic or
RegexNodeKind
.Setloopatomic:
1218
case
RegexNodeKind
.Oneloop or
RegexNodeKind
.Notoneloop or
RegexNodeKind
.Setloop or
RegexNodeKind
.Onelazy or
RegexNodeKind
.Notonelazy or
RegexNodeKind
.Setlazy when required.M == required.N:
1219
case
RegexNodeKind
.Beginning or
RegexNodeKind
.Start or
RegexNodeKind
.Bol
1220
or
RegexNodeKind
.End or
RegexNodeKind
.EndZ or
RegexNodeKind
.Eol
1221
or
RegexNodeKind
.Boundary or
RegexNodeKind
.ECMABoundary
1222
or
RegexNodeKind
.NonBoundary or
RegexNodeKind
.NonECMABoundary:
1252
var newAlternate = new RegexNode(
RegexNodeKind
.Alternate, alternation.Options);
1260
if (alternation.Parent is RegexNode { Kind:
RegexNodeKind
.Atomic })
1262
var atomic = new RegexNode(
RegexNodeKind
.Atomic, alternation.Options);
1269
var newConcat = new RegexNode(
RegexNodeKind
.Concatenate, alternation.Options);
1285
Debug.Assert(node.Kind ==
RegexNodeKind
.Alternate);
1296
case
RegexNodeKind
.Empty when !seenEmpty:
1300
case
RegexNodeKind
.Empty:
1301
case
RegexNodeKind
.Nothing:
1328
Debug.Assert(alternation.Kind ==
RegexNodeKind
.Alternate);
1355
if (startingNode.Kind ==
RegexNodeKind
.One)
1375
if (startingNode.Kind ==
RegexNodeKind
.One)
1389
Debug.Assert(startingNode.Kind ==
RegexNodeKind
.Multi);
1420
new RegexNode(
RegexNodeKind
.One, startingNodeOptions, startingSpan[0]) :
1421
new RegexNode(
RegexNodeKind
.Multi, startingNodeOptions, startingSpan.ToString());
1422
var newAlternate = new RegexNode(
RegexNodeKind
.Alternate, startingNodeOptions);
1426
ProcessOneOrMulti(branch.Kind ==
RegexNodeKind
.Concatenate ? branch.Child(0) : branch, startingSpan);
1434
if (node.Kind ==
RegexNodeKind
.One)
1438
node.Kind =
RegexNodeKind
.Empty;
1443
Debug.Assert(node.Kind ==
RegexNodeKind
.Multi);
1447
node.Kind =
RegexNodeKind
.Empty;
1452
node.Kind =
RegexNodeKind
.One;
1464
if (alternation.Parent is RegexNode parent && parent.Kind ==
RegexNodeKind
.Atomic)
1466
var atomic = new RegexNode(
RegexNodeKind
.Atomic, startingNodeOptions);
1471
var newConcat = new RegexNode(
RegexNodeKind
.Concatenate, startingNodeOptions);
1491
RegexNode branch = Kind ==
RegexNodeKind
.Concatenate ? Child(0) : this;
1492
return branch.Kind is
RegexNodeKind
.One or
RegexNodeKind
.Multi ? branch : null;
1498
Debug.Assert(Kind is
RegexNodeKind
.One or
RegexNodeKind
.Multi || (IsOneFamily && M > 0));
1513
Debug.Assert(Kind is
RegexNodeKind
.Alternate);
1537
if (startingLiteralNode.IsOneFamily || startingLiteralNode.Kind is
RegexNodeKind
.Multi)
1583
case
RegexNodeKind
.One:
1584
case
RegexNodeKind
.Oneloop or
RegexNodeKind
.Oneloopatomic or
RegexNodeKind
.Onelazy when node.M > 0:
1585
case
RegexNodeKind
.Notone:
1586
case
RegexNodeKind
.Notoneloop or
RegexNodeKind
.Notoneloopatomic or
RegexNodeKind
.Notonelazy when node.M > 0:
1587
case
RegexNodeKind
.Set:
1588
case
RegexNodeKind
.Setloop or
RegexNodeKind
.Setloopatomic or
RegexNodeKind
.Setlazy when node.M > 0:
1589
case
RegexNodeKind
.Multi:
1592
case
RegexNodeKind
.Atomic:
1593
case
RegexNodeKind
.Concatenate:
1594
case
RegexNodeKind
.Capture:
1595
case
RegexNodeKind
.Group:
1596
case
RegexNodeKind
.Loop or
RegexNodeKind
.Lazyloop when node.M > 0:
1597
case
RegexNodeKind
.PositiveLookaround when allowZeroWidth:
1618
case
RegexNodeKind
.One or
RegexNodeKind
.Oneloop or
RegexNodeKind
.Oneloopatomic or
RegexNodeKind
.Onelazy:
1621
case
RegexNodeKind
.Notone or
RegexNodeKind
.Notoneloop or
RegexNodeKind
.Notoneloopatomic or
RegexNodeKind
.Notonelazy:
1624
case
RegexNodeKind
.Set or
RegexNodeKind
.Setloop or
RegexNodeKind
.Setloopatomic or
RegexNodeKind
.Setlazy:
1640
case
RegexNodeKind
.Multi:
1683
Debug.Assert(Kind ==
RegexNodeKind
.Concatenate);
1689
return new RegexNode(
RegexNodeKind
.Empty, Options);
1699
if (child.Kind ==
RegexNodeKind
.Nothing)
1725
Debug.Assert(Kind ==
RegexNodeKind
.Concatenate);
1742
if (at.Kind ==
RegexNodeKind
.Concatenate &&
1761
else if (at.Kind is
RegexNodeKind
.Multi or
RegexNodeKind
.One)
1775
if (prev.Kind ==
RegexNodeKind
.One)
1777
prev.Kind =
RegexNodeKind
.Multi;
1782
((at.Kind ==
RegexNodeKind
.One) ? $"{prev.Str}{at.Ch}" : prev.Str + at.Str) :
1783
((at.Kind ==
RegexNodeKind
.One) ? $"{at.Ch}{prev.Str}" : at.Str + prev.Str);
1785
else if (at.Kind ==
RegexNodeKind
.Empty)
1808
Debug.Assert(Kind ==
RegexNodeKind
.Concatenate);
1846
case
RegexNodeKind
.Oneloop or
RegexNodeKind
.Oneloopatomic or
RegexNodeKind
.Onelazy or
RegexNodeKind
.Notoneloop or
RegexNodeKind
.Notoneloopatomic or
RegexNodeKind
.Notonelazy when nextNode.Kind == currentNode.Kind && currentNode.Ch == nextNode.Ch:
1847
case
RegexNodeKind
.Setloop or
RegexNodeKind
.Setloopatomic or
RegexNodeKind
.Setlazy when nextNode.Kind == currentNode.Kind && currentNode.Str == nextNode.Str:
1849
currentNode.Kind is
RegexNodeKind
.Oneloopatomic or
RegexNodeKind
.Notoneloopatomic or
RegexNodeKind
.Setloopatomic)
1872
case
RegexNodeKind
.Oneloop or
RegexNodeKind
.Onelazy when nextNode.Kind ==
RegexNodeKind
.One && currentNode.Ch == nextNode.Ch:
1873
case
RegexNodeKind
.Notoneloop or
RegexNodeKind
.Notonelazy when nextNode.Kind ==
RegexNodeKind
.Notone && currentNode.Ch == nextNode.Ch:
1874
case
RegexNodeKind
.Setloop or
RegexNodeKind
.Setlazy when nextNode.Kind ==
RegexNodeKind
.Set && currentNode.Str == nextNode.Str:
1888
case
RegexNodeKind
.Oneloop or
RegexNodeKind
.Onelazy when
1889
nextNode.Kind ==
RegexNodeKind
.Multi &&
1922
nextNode.Kind =
RegexNodeKind
.One;
1940
case
RegexNodeKind
.One when (nextNode.Kind is
RegexNodeKind
.Oneloop or
RegexNodeKind
.Oneloopatomic or
RegexNodeKind
.Onelazy) && currentNode.Ch == nextNode.Ch:
1941
case
RegexNodeKind
.Notone when (nextNode.Kind is
RegexNodeKind
.Notoneloop or
RegexNodeKind
.Notoneloopatomic or
RegexNodeKind
.Notonelazy) && currentNode.Ch == nextNode.Ch:
1942
case
RegexNodeKind
.Set when (nextNode.Kind is
RegexNodeKind
.Setloop or
RegexNodeKind
.Setloopatomic or
RegexNodeKind
.Setlazy) && currentNode.Str == nextNode.Str:
1955
case
RegexNodeKind
.Notone when nextNode.Kind == currentNode.Kind && currentNode.Ch == nextNode.Ch:
1956
case
RegexNodeKind
.Set when nextNode.Kind ==
RegexNodeKind
.Set && currentNode.Str == nextNode.Str:
1957
currentNode.MakeRep(
RegexNodeKind
.Oneloop, 2, 2);
1962
case
RegexNodeKind
.Beginning or
RegexNodeKind
.Start or
1963
RegexNodeKind
.End or
RegexNodeKind
.EndZ or
1964
RegexNodeKind
.Bol or
RegexNodeKind
.Eol or
1965
RegexNodeKind
.Boundary or
RegexNodeKind
.NonBoundary or
1966
RegexNodeKind
.ECMABoundary or
RegexNodeKind
.NonECMABoundary
2010
if (Kind is not
RegexNodeKind
.Concatenate)
2034
while (node.Kind is
RegexNodeKind
.Capture or
RegexNodeKind
.Concatenate)
2042
case
RegexNodeKind
.Oneloop or
RegexNodeKind
.Notoneloop or
RegexNodeKind
.Setloop when CanBeMadeAtomic(node, subsequent, iterateNullableSubsequent: true, allowLazy: false):
2051
case
RegexNodeKind
.Onelazy or
RegexNodeKind
.Notonelazy or
RegexNodeKind
.Setlazy when CanBeMadeAtomic(node, subsequent, iterateNullableSubsequent: false, allowLazy: true):
2067
node.Kind -=
RegexNodeKind
.Onelazy -
RegexNodeKind
.Oneloop; // lazy to greedy
2071
case
RegexNodeKind
.Loop when CanBeMadeAtomic(node, subsequent, iterateNullableSubsequent: true, allowLazy: false):
2072
case
RegexNodeKind
.Lazyloop when CanBeMadeAtomic(node, subsequent, iterateNullableSubsequent: false, allowLazy: true):
2086
while (loopChild.Kind is
RegexNodeKind
.Capture or
RegexNodeKind
.Concatenate)
2098
RegexNodeKind
.Boundary or
RegexNodeKind
.ECMABoundary or
2099
RegexNodeKind
.Multi or
2100
RegexNodeKind
.One or
RegexNodeKind
.Notone or
RegexNodeKind
.Set &&
2105
else if (node.Kind is
RegexNodeKind
.Loop or
RegexNodeKind
.Lazyloop)
2109
goto case
RegexNodeKind
.Loop;
2117
case
RegexNodeKind
.Loop:
2127
case
RegexNodeKind
.Lazyloop:
2137
case
RegexNodeKind
.Alternate or
RegexNodeKind
.BackreferenceConditional or
RegexNodeKind
.ExpressionConditional:
2148
for (int b = node.Kind ==
RegexNodeKind
.ExpressionConditional ? 1 : 0; b < alternateBranches; b++)
2162
Debug.Assert(Kind is
RegexNodeKind
.PositiveLookaround or
RegexNodeKind
.NegativeLookaround);
2170
if (Kind is
RegexNodeKind
.NegativeLookaround && ContainsKind(Child(0), [
RegexNodeKind
.Backreference,
RegexNodeKind
.BackreferenceConditional]) is false)
2185
if (node is { Kind:
RegexNodeKind
.Capture, N: -1 })
2216
if (Kind is
RegexNodeKind
.PositiveLookaround)
2219
child.Kind is
RegexNodeKind
.Empty)
2224
else if (Kind is
RegexNodeKind
.NegativeLookaround)
2229
if (child.Kind is
RegexNodeKind
.Empty)
2231
Kind =
RegexNodeKind
.Nothing;
2239
private static bool IsZeroWidthAssertion(
RegexNodeKind
kind) => kind is
2240
RegexNodeKind
.PositiveLookaround or
RegexNodeKind
.NegativeLookaround or
2241
RegexNodeKind
.Beginning or
RegexNodeKind
.Start or
2242
RegexNodeKind
.Bol or
RegexNodeKind
.Eol or
2243
RegexNodeKind
.End or
RegexNodeKind
.EndZ or
2244
RegexNodeKind
.Boundary or
RegexNodeKind
.ECMABoundary or
2245
RegexNodeKind
.NonBoundary or
RegexNodeKind
.NonECMABoundary or
2246
RegexNodeKind
.UpdateBumpalong;
2250
private static bool? ContainsKind(RegexNode node, ReadOnlySpan<
RegexNodeKind
> kinds)
2252
foreach (
RegexNodeKind
kind in kinds)
2282
Debug.Assert(Kind ==
RegexNodeKind
.BackreferenceConditional);
2291
AddChild(new RegexNode(
RegexNodeKind
.Empty, Options));
2300
Debug.Assert(Kind ==
RegexNodeKind
.ExpressionConditional);
2309
AddChild(new RegexNode(
RegexNodeKind
.Empty, Options));
2318
if (condition.Kind ==
RegexNodeKind
.PositiveLookaround && (condition.Options & RegexOptions.RightToLeft) == 0)
2345
while (node.Kind is
RegexNodeKind
.Capture or
RegexNodeKind
.Concatenate)
2363
case
RegexNodeKind
.Concatenate:
2364
case
RegexNodeKind
.Capture:
2365
case
RegexNodeKind
.Atomic:
2369
case
RegexNodeKind
.Loop or
RegexNodeKind
.Lazyloop when subsequent.M > 0:
2377
case
RegexNodeKind
.PositiveLookaround when (subsequent.Options & RegexOptions.RightToLeft) == 0:
2401
case
RegexNodeKind
.Alternate:
2402
case
RegexNodeKind
.ExpressionConditional when childCount is 3: // condition, yes, and no branch
2417
case
RegexNodeKind
.Oneloop:
2418
case
RegexNodeKind
.Onelazy when allowLazy:
2421
case
RegexNodeKind
.One when node.Ch != subsequent.Ch:
2422
case
RegexNodeKind
.Notone when node.Ch == subsequent.Ch:
2423
case
RegexNodeKind
.Set when !RegexCharClass.CharInClass(node.Ch, subsequent.Str!):
2424
case
RegexNodeKind
.Onelazy or
RegexNodeKind
.Oneloop or
RegexNodeKind
.Oneloopatomic when subsequent.M > 0 && node.Ch != subsequent.Ch:
2425
case
RegexNodeKind
.Notonelazy or
RegexNodeKind
.Notoneloop or
RegexNodeKind
.Notoneloopatomic when subsequent.M > 0 && node.Ch == subsequent.Ch:
2426
case
RegexNodeKind
.Setlazy or
RegexNodeKind
.Setloop or
RegexNodeKind
.Setloopatomic when subsequent.M > 0 && !RegexCharClass.CharInClass(node.Ch, subsequent.Str!):
2427
case
RegexNodeKind
.Multi when node.Ch != subsequent.Str![0]:
2428
case
RegexNodeKind
.End:
2429
case
RegexNodeKind
.EndZ or
RegexNodeKind
.Eol when node.Ch != '\n':
2430
case
RegexNodeKind
.Boundary when node.M > 0 && RegexCharClass.IsBoundaryWordChar(node.Ch):
2431
case
RegexNodeKind
.NonBoundary when node.M > 0 && !RegexCharClass.IsBoundaryWordChar(node.Ch):
2432
case
RegexNodeKind
.ECMABoundary when node.M > 0 && RegexCharClass.IsECMAWordChar(node.Ch):
2433
case
RegexNodeKind
.NonECMABoundary when node.M > 0 && !RegexCharClass.IsECMAWordChar(node.Ch):
2436
case
RegexNodeKind
.Onelazy or
RegexNodeKind
.Oneloop or
RegexNodeKind
.Oneloopatomic when subsequent.M == 0 && node.Ch != subsequent.Ch:
2437
case
RegexNodeKind
.Notonelazy or
RegexNodeKind
.Notoneloop or
RegexNodeKind
.Notoneloopatomic when subsequent.M == 0 && node.Ch == subsequent.Ch:
2438
case
RegexNodeKind
.Setlazy or
RegexNodeKind
.Setloop or
RegexNodeKind
.Setloopatomic when subsequent.M == 0 && !RegexCharClass.CharInClass(node.Ch, subsequent.Str!):
2447
case
RegexNodeKind
.Notoneloop:
2448
case
RegexNodeKind
.Notonelazy when allowLazy:
2451
case
RegexNodeKind
.One when node.Ch == subsequent.Ch:
2452
case
RegexNodeKind
.Onelazy or
RegexNodeKind
.Oneloop or
RegexNodeKind
.Oneloopatomic when subsequent.M > 0 && node.Ch == subsequent.Ch:
2453
case
RegexNodeKind
.Multi when node.Ch == subsequent.Str![0]:
2454
case
RegexNodeKind
.End:
2457
case
RegexNodeKind
.Onelazy or
RegexNodeKind
.Oneloop or
RegexNodeKind
.Oneloopatomic when subsequent.M == 0 && node.Ch == subsequent.Ch:
2466
case
RegexNodeKind
.Setloop:
2467
case
RegexNodeKind
.Setlazy when allowLazy:
2470
case
RegexNodeKind
.One when !RegexCharClass.CharInClass(subsequent.Ch, node.Str!):
2471
case
RegexNodeKind
.Set when !RegexCharClass.MayOverlap(node.Str!, subsequent.Str!):
2472
case
RegexNodeKind
.Onelazy or
RegexNodeKind
.Oneloop or
RegexNodeKind
.Oneloopatomic when subsequent.M > 0 && !RegexCharClass.CharInClass(subsequent.Ch, node.Str!):
2473
case
RegexNodeKind
.Setlazy or
RegexNodeKind
.Setloop or
RegexNodeKind
.Setloopatomic when subsequent.M > 0 && !RegexCharClass.MayOverlap(node.Str!, subsequent.Str!):
2474
case
RegexNodeKind
.Multi when !RegexCharClass.CharInClass(subsequent.Str![0], node.Str!):
2475
case
RegexNodeKind
.End:
2476
case
RegexNodeKind
.EndZ or
RegexNodeKind
.Eol when !RegexCharClass.CharInClass('\n', node.Str!):
2477
case
RegexNodeKind
.Boundary when node.M > 0 && RegexCharClass.IsKnownWordClassSubset(node.Str!):
2478
case
RegexNodeKind
.NonBoundary when node.M > 0 && node.Str is RegexCharClass.NotWordClass or RegexCharClass.NotDigitClass:
2479
case
RegexNodeKind
.ECMABoundary when node.M > 0 && node.Str is RegexCharClass.ECMAWordClass or RegexCharClass.ECMADigitClass:
2480
case
RegexNodeKind
.NonECMABoundary when node.M > 0 && node.Str is RegexCharClass.NotECMAWordClass or RegexCharClass.NotDigitClass:
2483
case
RegexNodeKind
.Onelazy or
RegexNodeKind
.Oneloop or
RegexNodeKind
.Oneloopatomic when subsequent.M == 0 && !RegexCharClass.CharInClass(subsequent.Ch, node.Str!):
2484
case
RegexNodeKind
.Setlazy or
RegexNodeKind
.Setloop or
RegexNodeKind
.Setloopatomic when subsequent.M == 0 && !RegexCharClass.MayOverlap(node.Str!, subsequent.Str!):
2493
case
RegexNodeKind
.Loop:
2494
case
RegexNodeKind
.Lazyloop when allowLazy:
2517
case
RegexNodeKind
.One when !CharInStartingOrEndingSet(subsequent.Ch):
2518
case
RegexNodeKind
.Set when !MayOverlapStartingOrEndingSet(subsequent.Str!):
2519
case
RegexNodeKind
.Onelazy or
RegexNodeKind
.Oneloop or
RegexNodeKind
.Oneloopatomic when subsequent.M > 0 && !CharInStartingOrEndingSet(subsequent.Ch):
2520
case
RegexNodeKind
.Setlazy or
RegexNodeKind
.Setloop or
RegexNodeKind
.Setloopatomic when subsequent.M > 0 && !MayOverlapStartingOrEndingSet(subsequent.Str!):
2521
case
RegexNodeKind
.Multi when !CharInStartingOrEndingSet(subsequent.Str![0]):
2522
case
RegexNodeKind
.End:
2523
case
RegexNodeKind
.EndZ or
RegexNodeKind
.Eol when !CharInStartingOrEndingSet('\n'):
2524
case
RegexNodeKind
.Boundary when node.M > 0 && RegexCharClass.IsKnownWordClassSubset(loopStartingSet) && RegexCharClass.IsKnownWordClassSubset(loopEndingSet):
2525
case
RegexNodeKind
.NonBoundary when node.M > 0 && (loopStartingSet is RegexCharClass.NotWordClass or RegexCharClass.NotDigitClass) && (loopEndingSet is RegexCharClass.NotWordClass or RegexCharClass.NotDigitClass):
2526
case
RegexNodeKind
.ECMABoundary when node.M > 0 && (loopStartingSet is RegexCharClass.ECMAWordClass or RegexCharClass.ECMADigitClass) && (loopEndingSet is RegexCharClass.ECMAWordClass or RegexCharClass.ECMADigitClass):
2527
case
RegexNodeKind
.NonECMABoundary when node.M > 0 && (loopStartingSet is RegexCharClass.NotECMAWordClass or RegexCharClass.NotDigitClass) && (loopEndingSet is RegexCharClass.NotECMAWordClass or RegexCharClass.NotDigitClass):
2530
case
RegexNodeKind
.Onelazy or
RegexNodeKind
.Oneloop or
RegexNodeKind
.Oneloopatomic when subsequent.M == 0 && !CharInStartingOrEndingSet(subsequent.Ch):
2531
case
RegexNodeKind
.Setlazy or
RegexNodeKind
.Setloop or
RegexNodeKind
.Setloopatomic when subsequent.M == 0 && !MayOverlapStartingOrEndingSet(subsequent.Str!):
2559
case
RegexNodeKind
.Atomic:
2560
case
RegexNodeKind
.Alternate:
2561
case
RegexNodeKind
.Capture:
2565
case
RegexNodeKind
.Concatenate:
2602
RegexNodeKind
.Alternate => true,
2603
RegexNodeKind
.Loop or
RegexNodeKind
.Lazyloop when M != N => true,
2604
RegexNodeKind
.Oneloop or
RegexNodeKind
.Onelazy or
2605
RegexNodeKind
.Notoneloop or
RegexNodeKind
.Notonelazy or
2606
RegexNodeKind
.Setloop or
RegexNodeKind
.Setlazy when M != N => true,
2650
Debug.Assert(node.Kind is not
RegexNodeKind
.Concatenate, "The existing logic assumes that the node itself isn't a concatenation.");
2663
case
RegexNodeKind
.Atomic:
2664
case
RegexNodeKind
.Alternate:
2665
case
RegexNodeKind
.Capture:
2669
case
RegexNodeKind
.Concatenate:
2705
case
RegexNodeKind
.One:
2706
case
RegexNodeKind
.Notone:
2707
case
RegexNodeKind
.Set:
2711
case
RegexNodeKind
.Multi:
2715
case
RegexNodeKind
.Notonelazy:
2716
case
RegexNodeKind
.Notoneloop:
2717
case
RegexNodeKind
.Notoneloopatomic:
2718
case
RegexNodeKind
.Onelazy:
2719
case
RegexNodeKind
.Oneloop:
2720
case
RegexNodeKind
.Oneloopatomic:
2721
case
RegexNodeKind
.Setlazy:
2722
case
RegexNodeKind
.Setloop:
2723
case
RegexNodeKind
.Setloopatomic:
2727
case
RegexNodeKind
.Lazyloop:
2728
case
RegexNodeKind
.Loop:
2732
case
RegexNodeKind
.Alternate:
2745
case
RegexNodeKind
.BackreferenceConditional:
2749
case
RegexNodeKind
.ExpressionConditional:
2753
case
RegexNodeKind
.Concatenate:
2765
case
RegexNodeKind
.Atomic:
2766
case
RegexNodeKind
.Capture:
2767
case
RegexNodeKind
.Group:
2772
case
RegexNodeKind
.Empty:
2773
case
RegexNodeKind
.Nothing:
2774
case
RegexNodeKind
.UpdateBumpalong:
2778
case
RegexNodeKind
.Beginning:
2779
case
RegexNodeKind
.Bol:
2780
case
RegexNodeKind
.Boundary:
2781
case
RegexNodeKind
.ECMABoundary:
2782
case
RegexNodeKind
.End:
2783
case
RegexNodeKind
.EndZ:
2784
case
RegexNodeKind
.Eol:
2785
case
RegexNodeKind
.NonBoundary:
2786
case
RegexNodeKind
.NonECMABoundary:
2787
case
RegexNodeKind
.Start:
2788
case
RegexNodeKind
.NegativeLookaround:
2789
case
RegexNodeKind
.PositiveLookaround:
2791
case
RegexNodeKind
.Backreference:
2799
goto case
RegexNodeKind
.Empty;
2818
case
RegexNodeKind
.One:
2819
case
RegexNodeKind
.Notone:
2820
case
RegexNodeKind
.Set:
2824
case
RegexNodeKind
.Multi:
2828
case
RegexNodeKind
.Notonelazy or
RegexNodeKind
.Notoneloop or
RegexNodeKind
.Notoneloopatomic or
2829
RegexNodeKind
.Onelazy or
RegexNodeKind
.Oneloop or
RegexNodeKind
.Oneloopatomic or
2830
RegexNodeKind
.Setlazy or
RegexNodeKind
.Setloop or
RegexNodeKind
.Setloopatomic:
2834
case
RegexNodeKind
.Loop or
RegexNodeKind
.Lazyloop:
2849
case
RegexNodeKind
.Alternate:
2872
case
RegexNodeKind
.BackreferenceConditional:
2873
case
RegexNodeKind
.ExpressionConditional:
2876
int i = Kind ==
RegexNodeKind
.BackreferenceConditional ? 0 : 1;
2882
case
RegexNodeKind
.Concatenate:
2904
case
RegexNodeKind
.Atomic:
2905
case
RegexNodeKind
.Capture:
2910
case
RegexNodeKind
.Empty:
2911
case
RegexNodeKind
.Nothing:
2912
case
RegexNodeKind
.UpdateBumpalong:
2913
case
RegexNodeKind
.Beginning:
2914
case
RegexNodeKind
.Bol:
2915
case
RegexNodeKind
.Boundary:
2916
case
RegexNodeKind
.ECMABoundary:
2917
case
RegexNodeKind
.End:
2918
case
RegexNodeKind
.EndZ:
2919
case
RegexNodeKind
.Eol:
2920
case
RegexNodeKind
.NonBoundary:
2921
case
RegexNodeKind
.NonECMABoundary:
2922
case
RegexNodeKind
.Start:
2923
case
RegexNodeKind
.PositiveLookaround:
2924
case
RegexNodeKind
.NegativeLookaround:
2928
case
RegexNodeKind
.Backreference:
2936
goto case
RegexNodeKind
.Empty;
2959
Debug.Assert(Kind ==
RegexNodeKind
.Concatenate, $"Expected Concatenate, got {Kind}");
2972
if (child.Kind is
RegexNodeKind
.One)
2985
else if (child.Kind is
RegexNodeKind
.Multi)
2997
else if (child.Kind is
RegexNodeKind
.Set ||
2998
(child.Kind is
RegexNodeKind
.Setloop or
RegexNodeKind
.Setlazy or
RegexNodeKind
.Setloopatomic && child.M == child.N))
3007
vsb.Append((char)(twoChars[0] | 0x20), child.Kind is
RegexNodeKind
.Set ? 1 : child.M);
3009
else if (child.Kind is
RegexNodeKind
.Empty)
3060
Debug.Assert(Kind ==
RegexNodeKind
.Concatenate, $"Expected Concatenate, got {Kind}");
3064
RegexNodeKind
.One or
RegexNodeKind
.Notone or
RegexNodeKind
.Set => true,
3065
RegexNodeKind
.Multi => true,
3066
RegexNodeKind
.Oneloop or
RegexNodeKind
.Onelazy or
RegexNodeKind
.Oneloopatomic or
3067
RegexNodeKind
.Notoneloop or
RegexNodeKind
.Notonelazy or
RegexNodeKind
.Notoneloopatomic or
3068
RegexNodeKind
.Setloop or
RegexNodeKind
.Setlazy or
RegexNodeKind
.Setloopatomic
3110
return new RegexNode(
RegexNodeKind
.Empty, Options);
3116
case <= MultiVsRepeaterLimit when Kind ==
RegexNodeKind
.One:
3122
Kind =
RegexNodeKind
.Multi;
3131
case
RegexNodeKind
.One:
3132
case
RegexNodeKind
.Notone:
3133
case
RegexNodeKind
.Set:
3134
MakeRep(lazy ?
RegexNodeKind
.Onelazy :
RegexNodeKind
.Oneloop, min, max);
3138
var result = new RegexNode(lazy ?
RegexNodeKind
.Lazyloop :
RegexNodeKind
.Loop, Options, min, max);
3261
public bool IsSetFamily => Kind is
RegexNodeKind
.Set or
RegexNodeKind
.Setloop or
RegexNodeKind
.Setloopatomic or
RegexNodeKind
.Setlazy;
3264
public bool IsOneFamily => Kind is
RegexNodeKind
.One or
RegexNodeKind
.Oneloop or
RegexNodeKind
.Oneloopatomic or
RegexNodeKind
.Onelazy;
3267
public bool IsNotoneFamily => Kind is
RegexNodeKind
.Notone or
RegexNodeKind
.Notoneloop or
RegexNodeKind
.Notoneloopatomic or
RegexNodeKind
.Notonelazy;
3318
case
RegexNodeKind
.Oneloop:
3319
case
RegexNodeKind
.Oneloopatomic:
3320
case
RegexNodeKind
.Notoneloop:
3321
case
RegexNodeKind
.Notoneloopatomic:
3322
case
RegexNodeKind
.Onelazy:
3323
case
RegexNodeKind
.Notonelazy:
3324
case
RegexNodeKind
.One:
3325
case
RegexNodeKind
.Notone:
3328
case
RegexNodeKind
.Capture:
3335
case
RegexNodeKind
.Backreference:
3336
case
RegexNodeKind
.BackreferenceConditional:
3339
case
RegexNodeKind
.Multi:
3347
case
RegexNodeKind
.Set:
3348
case
RegexNodeKind
.Setloop:
3349
case
RegexNodeKind
.Setloopatomic:
3350
case
RegexNodeKind
.Setlazy:
3357
case
RegexNodeKind
.Oneloop:
3358
case
RegexNodeKind
.Oneloopatomic:
3359
case
RegexNodeKind
.Notoneloop:
3360
case
RegexNodeKind
.Notoneloopatomic:
3361
case
RegexNodeKind
.Onelazy:
3362
case
RegexNodeKind
.Notonelazy:
3363
case
RegexNodeKind
.Setloop:
3364
case
RegexNodeKind
.Setloopatomic:
3365
case
RegexNodeKind
.Setlazy:
3366
case
RegexNodeKind
.Loop:
3367
case
RegexNodeKind
.Lazyloop:
System\Text\RegularExpressions\RegexParser.cs (60)
277
StartGroup(new RegexNode(
RegexNodeKind
.Capture, (_options & ~RegexOptions.IgnoreCase), 0, -1));
347
_unit = new RegexNode(
RegexNodeKind
.Set, _options & ~RegexOptions.IgnoreCase, setString);
394
_unit = new RegexNode((_options & RegexOptions.Multiline) != 0 ?
RegexNodeKind
.Bol :
RegexNodeKind
.Beginning, _options);
398
_unit = new RegexNode((_options & RegexOptions.Multiline) != 0 ?
RegexNodeKind
.Eol :
RegexNodeKind
.EndZ, _options);
403
new RegexNode(
RegexNodeKind
.Set, _options & ~RegexOptions.IgnoreCase, RegexCharClass.AnyClass) :
404
new RegexNode(
RegexNodeKind
.Notone, _options & ~RegexOptions.IgnoreCase, '\n');
521
_concatenation = new RegexNode(
RegexNodeKind
.Concatenate, _options);
759
return new RegexNode(
RegexNodeKind
.Group, _options);
763
return new RegexNode(
RegexNodeKind
.Capture, _options, _autocap++, -1);
776
RegexNodeKind
nodeType;
783
nodeType =
RegexNodeKind
.Group;
789
nodeType =
RegexNodeKind
.PositiveLookaround;
795
nodeType =
RegexNodeKind
.NegativeLookaround;
800
nodeType =
RegexNodeKind
.Atomic;
823
nodeType =
RegexNodeKind
.PositiveLookaround;
834
nodeType =
RegexNodeKind
.NegativeLookaround;
937
return new RegexNode(
RegexNodeKind
.Capture, _options, capnum, uncapnum);
959
return new RegexNode(
RegexNodeKind
.BackreferenceConditional, _options, capnum);
973
return new RegexNode(
RegexNodeKind
.BackreferenceConditional, _options, tmpCapnum);
978
nodeType =
RegexNodeKind
.ExpressionConditional;
1002
nodeType =
RegexNodeKind
.Group;
1004
if (_group!.Kind !=
RegexNodeKind
.ExpressionConditional)
1096
new RegexNode(
RegexNodeKind
.Set, (_options & ~RegexOptions.IgnoreCase), (_options & RegexOptions.ECMAScript) != 0 ? RegexCharClass.ECMAWordClass : RegexCharClass.WordClass);
1101
new RegexNode(
RegexNodeKind
.Set, (_options & ~RegexOptions.IgnoreCase), (_options & RegexOptions.ECMAScript) != 0 ? RegexCharClass.NotECMAWordClass : RegexCharClass.NotWordClass);
1106
new RegexNode(
RegexNodeKind
.Set, (_options & ~RegexOptions.IgnoreCase), (_options & RegexOptions.ECMAScript) != 0 ? RegexCharClass.ECMASpaceClass : RegexCharClass.SpaceClass);
1111
new RegexNode(
RegexNodeKind
.Set, (_options & ~RegexOptions.IgnoreCase), (_options & RegexOptions.ECMAScript) != 0 ? RegexCharClass.NotECMASpaceClass : RegexCharClass.NotSpaceClass);
1116
new RegexNode(
RegexNodeKind
.Set, (_options & ~RegexOptions.IgnoreCase), (_options & RegexOptions.ECMAScript) != 0 ? RegexCharClass.ECMADigitClass : RegexCharClass.DigitClass);
1121
new RegexNode(
RegexNodeKind
.Set, (_options & ~RegexOptions.IgnoreCase), (_options & RegexOptions.ECMAScript) != 0 ? RegexCharClass.NotECMADigitClass : RegexCharClass.NotDigitClass);
1138
return new RegexNode(
RegexNodeKind
.Set, (_options & ~RegexOptions.IgnoreCase), cc.ToStringClass());
1142
if (result != null && result.Kind ==
RegexNodeKind
.Backreference && (result.Options & RegexOptions.IgnoreCase) != 0)
1203
IsCaptureSlot(capnum) ? new RegexNode(
RegexNodeKind
.Backreference, _options, capnum) :
1235
return scanOnly ? null : new RegexNode(
RegexNodeKind
.Backreference, _options, capnum);
1249
return new RegexNode(
RegexNodeKind
.Backreference, _options, capnum);
1269
_capnames?[capname] is int tmpCapnum ? new RegexNode(
RegexNodeKind
.Backreference, _options, tmpCapnum) :
1345
return new RegexNode(
RegexNodeKind
.Backreference, _options, capnum);
1355
return new RegexNode(
RegexNodeKind
.Backreference, _options, capnum);
1367
return new RegexNode(
RegexNodeKind
.Backreference, _options, tmpCapnum);
1405
return new RegexNode(
RegexNodeKind
.Backreference, _options, capnum);
1653
private readonly
RegexNodeKind
TypeFromCode(char ch) =>
1656
'b' => (_options & RegexOptions.ECMAScript) != 0 ?
RegexNodeKind
.ECMABoundary :
RegexNodeKind
.Boundary,
1657
'B' => (_options & RegexOptions.ECMAScript) != 0 ?
RegexNodeKind
.NonECMABoundary :
RegexNodeKind
.NonBoundary,
1658
'A' =>
RegexNodeKind
.Beginning,
1659
'G' =>
RegexNodeKind
.Start,
1660
'Z' =>
RegexNodeKind
.EndZ,
1661
'z' =>
RegexNodeKind
.End,
1662
_ =>
RegexNodeKind
.Nothing,
2004
_concatenation!.AddChild(new RegexNode(
RegexNodeKind
.Multi, _options & ~RegexOptions.IgnoreCase, _pattern.Substring(pos, cch)));
2034
if (_group.Kind ==
RegexNodeKind
.ExpressionConditional && _group.ChildCount() == 0)
2050
_alternation = new RegexNode(
RegexNodeKind
.Alternate, _options);
2051
_concatenation = new RegexNode(
RegexNodeKind
.Concatenate, _options);
2059
if (_group!.Kind is
RegexNodeKind
.ExpressionConditional or
RegexNodeKind
.BackreferenceConditional)
2068
_concatenation = new RegexNode(
RegexNodeKind
.Concatenate, _options);
2074
if (_group!.Kind is
RegexNodeKind
.ExpressionConditional or
RegexNodeKind
.BackreferenceConditional)
2078
if (_group.Kind ==
RegexNodeKind
.BackreferenceConditional && _group.ChildCount() > 2 || _group.ChildCount() > 3)
System\Text\RegularExpressions\RegexPrefixAnalyzer.cs (224)
84
case
RegexNodeKind
.Atomic:
85
case
RegexNodeKind
.Capture:
90
case
RegexNodeKind
.Bol:
91
case
RegexNodeKind
.Eol:
92
case
RegexNodeKind
.Boundary:
93
case
RegexNodeKind
.ECMABoundary:
94
case
RegexNodeKind
.NonBoundary:
95
case
RegexNodeKind
.NonECMABoundary:
96
case
RegexNodeKind
.Beginning:
97
case
RegexNodeKind
.Start:
98
case
RegexNodeKind
.EndZ:
99
case
RegexNodeKind
.End:
100
case
RegexNodeKind
.Empty:
101
case
RegexNodeKind
.UpdateBumpalong:
102
case
RegexNodeKind
.PositiveLookaround:
103
case
RegexNodeKind
.NegativeLookaround:
112
case
RegexNodeKind
.One or
RegexNodeKind
.Oneloop or
RegexNodeKind
.Onelazy or
RegexNodeKind
.Oneloopatomic when !ignoreCase || !RegexCharClass.ParticipatesInCaseConversion(node.Ch):
114
int reps = node.Kind is
RegexNodeKind
.One ? 1 : Math.Min(node.M, MaxPrefixLength);
119
return node.Kind is
RegexNodeKind
.One || reps == node.N;
124
case
RegexNodeKind
.Multi:
156
case
RegexNodeKind
.Set or
RegexNodeKind
.Setloop or
RegexNodeKind
.Setlazy or
RegexNodeKind
.Setloopatomic when !RegexCharClass.IsNegated(node.Str!): // negated sets are too complex to analyze
164
int reps = node.Kind is
RegexNodeKind
.Set ? 1 : Math.Min(node.M, MaxPrefixLength);
209
return node.Kind is
RegexNodeKind
.Set || reps == node.N;
212
case
RegexNodeKind
.Concatenate:
226
case
RegexNodeKind
.Loop or
RegexNodeKind
.Lazyloop when node.M > 0:
242
case
RegexNodeKind
.Alternate:
363
case
RegexNodeKind
.Concatenate:
377
case
RegexNodeKind
.Alternate when !rtl: // for RTL we'd need to be matching the suffixes of the alternation cases
422
case
RegexNodeKind
.One:
427
case
RegexNodeKind
.Multi:
432
case
RegexNodeKind
.Oneloop or
RegexNodeKind
.Oneloopatomic or
RegexNodeKind
.Onelazy when node.M > 0:
439
case
RegexNodeKind
.Loop or
RegexNodeKind
.Lazyloop when node.M > 0:
454
case
RegexNodeKind
.Atomic:
455
case
RegexNodeKind
.Capture:
459
case
RegexNodeKind
.Bol:
460
case
RegexNodeKind
.Eol:
461
case
RegexNodeKind
.Boundary:
462
case
RegexNodeKind
.ECMABoundary:
463
case
RegexNodeKind
.NonBoundary:
464
case
RegexNodeKind
.NonECMABoundary:
465
case
RegexNodeKind
.Beginning:
466
case
RegexNodeKind
.Start:
467
case
RegexNodeKind
.EndZ:
468
case
RegexNodeKind
.End:
469
case
RegexNodeKind
.Empty:
470
case
RegexNodeKind
.UpdateBumpalong:
471
case
RegexNodeKind
.PositiveLookaround:
472
case
RegexNodeKind
.NegativeLookaround:
491
case
RegexNodeKind
.Atomic:
492
case
RegexNodeKind
.Capture:
493
case
RegexNodeKind
.Loop or
RegexNodeKind
.Lazyloop when node.M > 0:
497
case
RegexNodeKind
.Concatenate:
600
case
RegexNodeKind
.One:
609
case
RegexNodeKind
.Onelazy or
RegexNodeKind
.Oneloop or
RegexNodeKind
.Oneloopatomic when node.M > 0:
621
case
RegexNodeKind
.Multi:
633
case
RegexNodeKind
.Set:
641
case
RegexNodeKind
.Setlazy or
RegexNodeKind
.Setloop or
RegexNodeKind
.Setloopatomic when node.M > 0:
652
case
RegexNodeKind
.Notone:
658
case
RegexNodeKind
.Notonelazy or
RegexNodeKind
.Notoneloop or
RegexNodeKind
.Notoneloopatomic when node.M == node.N:
662
case
RegexNodeKind
.Beginning:
663
case
RegexNodeKind
.Bol:
664
case
RegexNodeKind
.Boundary:
665
case
RegexNodeKind
.ECMABoundary:
666
case
RegexNodeKind
.Empty:
667
case
RegexNodeKind
.End:
668
case
RegexNodeKind
.EndZ:
669
case
RegexNodeKind
.Eol:
670
case
RegexNodeKind
.NonBoundary:
671
case
RegexNodeKind
.NonECMABoundary:
672
case
RegexNodeKind
.UpdateBumpalong:
673
case
RegexNodeKind
.Start:
674
case
RegexNodeKind
.NegativeLookaround:
675
case
RegexNodeKind
.PositiveLookaround:
681
case
RegexNodeKind
.Atomic:
682
case
RegexNodeKind
.Group:
683
case
RegexNodeKind
.Capture:
686
case
RegexNodeKind
.Lazyloop or
RegexNodeKind
.Loop when node.M > 0:
696
case
RegexNodeKind
.Concatenate:
709
case
RegexNodeKind
.Alternate when thorough:
954
case
RegexNodeKind
.One or
RegexNodeKind
.Oneloop or
RegexNodeKind
.Onelazy or
RegexNodeKind
.Oneloopatomic:
959
return node.Kind is
RegexNodeKind
.One || node.M > 0 ? true : null;
963
case
RegexNodeKind
.Notone or
RegexNodeKind
.Notoneloop or
RegexNodeKind
.Notoneloopatomic or
RegexNodeKind
.Notonelazy:
977
return node.Kind is
RegexNodeKind
.Notone || node.M > 0 ? true : null;
981
case
RegexNodeKind
.Set or
RegexNodeKind
.Setloop or
RegexNodeKind
.Setlazy or
RegexNodeKind
.Setloopatomic:
996
node.Kind is
RegexNodeKind
.Set || node.M > 0 ? true :
1000
case
RegexNodeKind
.Multi:
1012
case
RegexNodeKind
.Empty:
1013
case
RegexNodeKind
.Nothing:
1014
case
RegexNodeKind
.Bol:
1015
case
RegexNodeKind
.Eol:
1016
case
RegexNodeKind
.Boundary:
1017
case
RegexNodeKind
.NonBoundary:
1018
case
RegexNodeKind
.ECMABoundary:
1019
case
RegexNodeKind
.NonECMABoundary:
1020
case
RegexNodeKind
.Beginning:
1021
case
RegexNodeKind
.Start:
1022
case
RegexNodeKind
.EndZ:
1023
case
RegexNodeKind
.End:
1024
case
RegexNodeKind
.UpdateBumpalong:
1025
case
RegexNodeKind
.PositiveLookaround:
1026
case
RegexNodeKind
.NegativeLookaround:
1030
case
RegexNodeKind
.Atomic:
1031
case
RegexNodeKind
.Capture:
1037
case
RegexNodeKind
.Loop:
1038
case
RegexNodeKind
.Lazyloop:
1050
case
RegexNodeKind
.Concatenate:
1081
case
RegexNodeKind
.Alternate:
1102
case
RegexNodeKind
.BackreferenceConditional:
1103
case
RegexNodeKind
.ExpressionConditional:
1104
int branchStart = node.Kind is
RegexNodeKind
.BackreferenceConditional ? 0 : 1;
1113
case
RegexNodeKind
.Backreference:
1138
while (node.Kind is
RegexNodeKind
.Atomic or
RegexNodeKind
.Capture)
1142
if (node.Kind !=
RegexNodeKind
.Concatenate)
1155
while (firstChild.Kind is
RegexNodeKind
.Atomic or
RegexNodeKind
.Capture)
1159
if (firstChild.Kind is not (
RegexNodeKind
.Setloop or
RegexNodeKind
.Setloopatomic or
RegexNodeKind
.Setlazy) || firstChild.N != int.MaxValue)
1167
if (nextChild.Kind ==
RegexNodeKind
.UpdateBumpalong)
1224
while ((nextChild.Kind is
RegexNodeKind
.Atomic or
RegexNodeKind
.Capture or
RegexNodeKind
.Concatenate) ||
1225
(nextChild.Kind is
RegexNodeKind
.Loop or
RegexNodeKind
.Lazyloop && nextChild.M >= 1))
1233
(nextChild.Kind is
RegexNodeKind
.Set || nextChild.M >= 1))
1279
case
RegexNodeKind
.PositiveLookaround:
1284
case
RegexNodeKind
.Bol:
1285
case
RegexNodeKind
.Eol:
1286
case
RegexNodeKind
.Beginning:
1287
case
RegexNodeKind
.Start:
1288
case
RegexNodeKind
.EndZ:
1289
case
RegexNodeKind
.End:
1290
case
RegexNodeKind
.Boundary:
1291
case
RegexNodeKind
.ECMABoundary:
1292
case
RegexNodeKind
.NegativeLookaround:
1293
case
RegexNodeKind
.Empty:
1297
case
RegexNodeKind
.Atomic:
1298
case
RegexNodeKind
.Capture:
1303
case
RegexNodeKind
.Loop or
RegexNodeKind
.Lazyloop when node.M >= 1:
1309
case
RegexNodeKind
.Concatenate:
1330
public static
RegexNodeKind
FindLeadingAnchor(RegexNode node) =>
1334
public static
RegexNodeKind
FindTrailingAnchor(RegexNode node) =>
1338
private static
RegexNodeKind
FindLeadingOrTrailingAnchor(RegexNode node, bool leading)
1344
return
RegexNodeKind
.Unknown;
1351
case
RegexNodeKind
.Bol:
1352
case
RegexNodeKind
.Eol:
1353
case
RegexNodeKind
.Beginning:
1354
case
RegexNodeKind
.Start:
1355
case
RegexNodeKind
.EndZ:
1356
case
RegexNodeKind
.End:
1360
case
RegexNodeKind
.Atomic:
1361
case
RegexNodeKind
.Capture:
1362
case
RegexNodeKind
.Loop or
RegexNodeKind
.Lazyloop when leading && node.M >= 1:
1363
case
RegexNodeKind
.PositiveLookaround when leading && (node.Options & RegexOptions.RightToLeft) == 0:
1373
case
RegexNodeKind
.Concatenate:
1380
RegexNodeKind
bestAnchorFound =
RegexNodeKind
.Unknown;
1388
case
RegexNodeKind
.Empty or
RegexNodeKind
.NegativeLookaround:
1389
case
RegexNodeKind
.PositiveLookaround when ((node.Options | tmpChild.Options) & RegexOptions.RightToLeft) != 0:
1390
case
RegexNodeKind
.Boundary or
RegexNodeKind
.ECMABoundary or
RegexNodeKind
.NonBoundary or
RegexNodeKind
.NonECMABoundary:
1394
case
RegexNodeKind
.PositiveLookaround:
1416
if (node.Child(i).Kind is not (
RegexNodeKind
.Empty or
RegexNodeKind
.PositiveLookaround or
RegexNodeKind
.NegativeLookaround))
1424
if (bestAnchorFound is not
RegexNodeKind
.Unknown)
1446
static
RegexNodeKind
ChooseBetterAnchor(
RegexNodeKind
anchor1,
RegexNodeKind
anchor2)
1449
anchor1 ==
RegexNodeKind
.Unknown ? anchor2 :
1450
anchor2 ==
RegexNodeKind
.Unknown ? anchor1 :
1454
static int RankAnchorQuality(
RegexNodeKind
node) =>
1457
RegexNodeKind
.Beginning => 3,
1458
RegexNodeKind
.Start => 3,
1459
RegexNodeKind
.End => 3,
1460
RegexNodeKind
.EndZ => 3,
1462
RegexNodeKind
.Bol => 2,
1463
RegexNodeKind
.Eol => 2,
1465
RegexNodeKind
.Boundary => 1,
1466
RegexNodeKind
.ECMABoundary => 1,
1472
static bool IsBestAnchor(
RegexNodeKind
anchor) =>
1474
anchor is
RegexNodeKind
.Beginning or
RegexNodeKind
.Start or
RegexNodeKind
.End or
RegexNodeKind
.EndZ;
1477
case
RegexNodeKind
.Alternate:
1481
RegexNodeKind
anchor = FindLeadingOrTrailingAnchor(node.Child(0), leading);
1482
if (anchor ==
RegexNodeKind
.Unknown)
1484
return
RegexNodeKind
.Unknown;
1494
return
RegexNodeKind
.Unknown;
1504
return
RegexNodeKind
.Unknown;
System\Text\RegularExpressions\RegexReplacement.cs (4)
36
Debug.Assert(concat.Kind ==
RegexNodeKind
.Concatenate, $"Expected Concatenate, got {concat.Kind}");
50
case
RegexNodeKind
.Multi:
54
case
RegexNodeKind
.One:
58
case
RegexNodeKind
.Backreference:
System\Text\RegularExpressions\RegexTreeAnalyzer.cs (16)
59
case
RegexNodeKind
.Atomic:
60
case
RegexNodeKind
.NegativeLookaround:
61
case
RegexNodeKind
.PositiveLookaround:
66
case
RegexNodeKind
.Capture:
71
case
RegexNodeKind
.Loop:
72
case
RegexNodeKind
.Lazyloop:
90
RegexNodeKind
.Atomic or
RegexNodeKind
.NegativeLookaround or
RegexNodeKind
.PositiveLookaround => true,
94
RegexNodeKind
.Alternate or
RegexNodeKind
.BackreferenceConditional or
RegexNodeKind
.ExpressionConditional => true,
97
RegexNodeKind
.Capture => true,
101
RegexNodeKind
.Concatenate => i == childCount - 1,
107
RegexNodeKind
.Loop or
RegexNodeKind
.Lazyloop when node.N == 1 => true,
System\Text\RegularExpressions\RegexWriter.cs (56)
14
private const
RegexNodeKind
BeforeChild = (
RegexNodeKind
)64;
15
private const
RegexNodeKind
AfterChild = (
RegexNodeKind
)128;
201
private void EmitFragment(
RegexNodeKind
nodeType, RegexNode node, int curIndex)
215
case
RegexNodeKind
.Concatenate | BeforeChild:
216
case
RegexNodeKind
.Concatenate | AfterChild:
217
case
RegexNodeKind
.Empty:
220
case
RegexNodeKind
.Alternate | BeforeChild:
228
case
RegexNodeKind
.Alternate | AfterChild:
247
case
RegexNodeKind
.BackreferenceConditional | BeforeChild:
260
case
RegexNodeKind
.BackreferenceConditional | AfterChild:
278
case
RegexNodeKind
.ExpressionConditional | BeforeChild:
290
case
RegexNodeKind
.ExpressionConditional | AfterChild:
311
case
RegexNodeKind
.Loop | BeforeChild:
312
case
RegexNodeKind
.Lazyloop | BeforeChild:
327
case
RegexNodeKind
.Loop | AfterChild:
328
case
RegexNodeKind
.Lazyloop | AfterChild:
331
int Lazy = (nodeType - (
RegexNodeKind
.Loop | AfterChild));
343
case
RegexNodeKind
.Capture | BeforeChild:
347
case
RegexNodeKind
.Capture | AfterChild:
351
case
RegexNodeKind
.PositiveLookaround | BeforeChild:
356
case
RegexNodeKind
.PositiveLookaround | AfterChild:
361
case
RegexNodeKind
.NegativeLookaround | BeforeChild:
367
case
RegexNodeKind
.NegativeLookaround | AfterChild:
373
case
RegexNodeKind
.Atomic | BeforeChild:
377
case
RegexNodeKind
.Atomic | AfterChild:
381
case
RegexNodeKind
.One:
382
case
RegexNodeKind
.Notone:
386
case
RegexNodeKind
.Notoneloop:
387
case
RegexNodeKind
.Notoneloopatomic:
388
case
RegexNodeKind
.Notonelazy:
389
case
RegexNodeKind
.Oneloop:
390
case
RegexNodeKind
.Oneloopatomic:
391
case
RegexNodeKind
.Onelazy:
394
Emit(((node.Kind is
RegexNodeKind
.Oneloop or
RegexNodeKind
.Oneloopatomic or
RegexNodeKind
.Onelazy) ?
403
case
RegexNodeKind
.Setloop:
404
case
RegexNodeKind
.Setloopatomic:
405
case
RegexNodeKind
.Setlazy:
419
case
RegexNodeKind
.Multi:
423
case
RegexNodeKind
.Set:
427
case
RegexNodeKind
.Backreference:
431
case
RegexNodeKind
.Nothing:
432
case
RegexNodeKind
.Bol:
433
case
RegexNodeKind
.Eol:
434
case
RegexNodeKind
.Boundary:
435
case
RegexNodeKind
.NonBoundary:
436
case
RegexNodeKind
.ECMABoundary:
437
case
RegexNodeKind
.NonECMABoundary:
438
case
RegexNodeKind
.Beginning:
439
case
RegexNodeKind
.Start:
440
case
RegexNodeKind
.EndZ:
441
case
RegexNodeKind
.End:
442
case
RegexNodeKind
.UpdateBumpalong:
System\Text\RegularExpressions\Symbolic\RegexNodeConverter.cs (49)
57
case
RegexNodeKind
.One:
61
case
RegexNodeKind
.Notone:
65
case
RegexNodeKind
.Set:
69
case
RegexNodeKind
.Multi:
84
case
RegexNodeKind
.Concatenate:
85
case
RegexNodeKind
.Alternate:
86
case
RegexNodeKind
.Loop:
87
case
RegexNodeKind
.Lazyloop:
88
case
RegexNodeKind
.Capture when node.N == -1: // N == -1 because balancing groups (which have N >= 0) aren't supported
106
case
RegexNodeKind
.Oneloop:
107
case
RegexNodeKind
.Onelazy:
108
case
RegexNodeKind
.Notoneloop:
109
case
RegexNodeKind
.Notonelazy:
117
result.AddLast(_builder.CreateLoop(_builder.CreateSingleton(bdd), node.Kind is
RegexNodeKind
.Onelazy or
RegexNodeKind
.Notonelazy, node.M, node.N));
121
case
RegexNodeKind
.Setloop:
122
case
RegexNodeKind
.Setlazy:
128
result.AddLast(_builder.CreateLoop(_builder.CreateSingleton(setBdd), node.Kind ==
RegexNodeKind
.Setlazy, node.M, node.N));
132
case
RegexNodeKind
.Empty:
133
case
RegexNodeKind
.UpdateBumpalong: // UpdateBumpalong is a directive relevant only to backtracking and can be ignored just like Empty
136
case
RegexNodeKind
.Nothing:
142
case
RegexNodeKind
.Beginning:
146
case
RegexNodeKind
.Bol:
151
case
RegexNodeKind
.End: // \z anchor
155
case
RegexNodeKind
.EndZ: // \Z anchor
160
case
RegexNodeKind
.Eol:
165
case
RegexNodeKind
.Boundary:
170
case
RegexNodeKind
.NonBoundary:
180
RegexNodeKind
.Atomic or
RegexNodeKind
.Setloopatomic or
RegexNodeKind
.Oneloopatomic or
RegexNodeKind
.Notoneloopatomic => SR.ExpressionDescription_AtomicSubexpressions,
181
RegexNodeKind
.Backreference => SR.ExpressionDescription_Backreference,
182
RegexNodeKind
.BackreferenceConditional => SR.ExpressionDescription_Conditional,
183
RegexNodeKind
.Capture => SR.ExpressionDescription_BalancingGroup,
184
RegexNodeKind
.ExpressionConditional => SR.ExpressionDescription_IfThenElse,
185
RegexNodeKind
.NegativeLookaround => SR.ExpressionDescription_NegativeLookaround,
186
RegexNodeKind
.PositiveLookaround => SR.ExpressionDescription_PositiveLookaround,
187
RegexNodeKind
.Start => SR.ExpressionDescription_ContiguousMatches,
195
string description = $"Unexpected ({nameof(
RegexNodeKind
)}: {node.Kind})";
211
case
RegexNodeKind
.Concatenate:
221
case
RegexNodeKind
.Alternate:
250
case
RegexNodeKind
.Loop:
251
case
RegexNodeKind
.Lazyloop:
260
result.AddLast(_builder.CreateLoop(body, node.Kind ==
RegexNodeKind
.Lazyloop, node.M, node.N));
267
Debug.Assert(node.Kind ==
RegexNodeKind
.Capture && node.N == -1);
285
Debug.Assert(rootResult.Count == 1 || root.Kind ==
RegexNodeKind
.Concatenate || root.Kind ==
RegexNodeKind
.Capture);
312
Debug.Assert(node.Kind ==
RegexNodeKind
.Set);
System\Text\RegularExpressions\Symbolic\SymbolicRegexKind.cs (16)
9
/// <summary>An empty node that matches a zero-width input (e.g. <see cref="
RegexNodeKind
.Empty"/>).</summary>
11
/// <summary>A node that matches a single character (i.e. <see cref="
RegexNodeKind
.One"/>, <see cref="
RegexNodeKind
.Notone"/>, or <see cref="
RegexNodeKind
.Set"/>).</summary>
13
/// <summary>A node that matches a sequence of nodes (i.e. <see cref="
RegexNodeKind
.Concatenate"/>).</summary>
15
/// <summary>A node that matches a loop (e.g. <see cref="
RegexNodeKind
.Loop"/>, <see cref="
RegexNodeKind
.Lazyloop"/>, <see cref="
RegexNodeKind
.Setloop"/>, etc.).</summary>
17
/// <summary>A node that matches if any of its nodes match and that matches them in a fixed order that mirrors how the backtracking engines operate (e.g. <see cref="
RegexNodeKind
.Alternate"/>).</summary>
20
/// <summary>A node that represents a beginning anchor (i.e. <see cref="
RegexNodeKind
.Beginning"/>).</summary>
22
/// <summary>A node that represents an ending anchor (i.e. <see cref="
RegexNodeKind
.End"/>).</summary>
24
/// <summary>A node that represents an ending \Z anchor (i.e. <see cref="
RegexNodeKind
.EndZ"/>).</summary>
28
/// <summary>A node that represents a beginning-of-line anchor (i.e. <see cref="
RegexNodeKind
.Bol"/>).</summary>
30
/// <summary>A node that represents a end-of-line anchor (i.e. <see cref="
RegexNodeKind
.Eol"/>).</summary>
32
/// <summary>A node that represents a word boundary anchor (i.e. <see cref="
RegexNodeKind
.Boundary"/>).</summary>
34
/// <summary>A node that represents a word non-boundary anchor (i.e. <see cref="
RegexNodeKind
.NonBoundary"/>).</summary>
System\Text\RegularExpressions\Symbolic\SymbolicRegexMatcher.cs (1)
211
findOptimizations.LeadingAnchor is not
RegexNodeKind
.Beginning)