@@ -208,4 +208,40 @@ extension RegexTests {
208
208
expectProgram ( for: " [abc] " , semanticLevel: . unicodeScalar, doesNotContain: [ . matchBitset] )
209
209
expectProgram ( for: " [abc] " , semanticLevel: . unicodeScalar, contains: [ . consumeBy] )
210
210
}
211
+
212
+ func testQuantificationForwardProgressCompile( ) {
213
+ // Unbounded quantification + non forward progressing inner nodes
214
+ // Expect to emit the position checking instructions
215
+ expectProgram ( for: #"(?:(?=a)){1,}"# , contains: [ . moveCurrentPosition, . condBranchSamePosition] )
216
+ expectProgram ( for: #"(?:\b)*"# , contains: [ . moveCurrentPosition, . condBranchSamePosition] )
217
+ expectProgram ( for: #"(?:(?#comment))+"# , contains: [ . moveCurrentPosition, . condBranchSamePosition] )
218
+ expectProgram ( for: #"(?:|)+"# , contains: [ . moveCurrentPosition, . condBranchSamePosition] )
219
+ expectProgram ( for: #"(?:\w|)+"# , contains: [ . moveCurrentPosition, . condBranchSamePosition] )
220
+ expectProgram ( for: #"(?:\w|(?i-i:))+"# , contains: [ . moveCurrentPosition, . condBranchSamePosition] )
221
+ expectProgram ( for: #"(?:\w|(?#comment))+"# , contains: [ . moveCurrentPosition, . condBranchSamePosition] )
222
+ expectProgram ( for: #"(?:\w|(?#comment)(?i-i:))+"# , contains: [ . moveCurrentPosition, . condBranchSamePosition] )
223
+ expectProgram ( for: #"(?:\w|(?i))+"# , contains: [ . moveCurrentPosition, . condBranchSamePosition] )
224
+
225
+ // Bounded quantification, don't emit position checking
226
+ expectProgram ( for: #"(?:(?=a)){1,4}"# , doesNotContain: [ . moveCurrentPosition, . condBranchSamePosition] )
227
+ expectProgram ( for: #"(?:\b)?"# , doesNotContain: [ . moveCurrentPosition, . condBranchSamePosition] )
228
+ expectProgram ( for: #"(?:(?#comment)){,4}"# , doesNotContain: [ . moveCurrentPosition, . condBranchSamePosition] )
229
+ expectProgram ( for: #"(?:|){,4}"# , doesNotContain: [ . moveCurrentPosition, . condBranchSamePosition] )
230
+ expectProgram ( for: #"(?:\w|){,4}"# , doesNotContain: [ . moveCurrentPosition, . condBranchSamePosition] )
231
+ expectProgram ( for: #"(?:\w|(?i-i:)){,4}"# , doesNotContain: [ . moveCurrentPosition, . condBranchSamePosition] )
232
+ expectProgram ( for: #"(?:\w|(?#comment)){,4}"# , doesNotContain: [ . moveCurrentPosition, . condBranchSamePosition] )
233
+ expectProgram ( for: #"(?:\w|(?#comment)(?i-i:)){,4}"# , doesNotContain: [ . moveCurrentPosition, . condBranchSamePosition] )
234
+ expectProgram ( for: #"(?:\w|(?i)){,4}"# , doesNotContain: [ . moveCurrentPosition, . condBranchSamePosition] )
235
+
236
+ // Inner node is a quantification that does not guarantee forward progress
237
+ expectProgram ( for: #"(a*)*"# , contains: [ . moveCurrentPosition, . condBranchSamePosition] )
238
+ expectProgram ( for: #"(a?)*"# , contains: [ . moveCurrentPosition, . condBranchSamePosition] )
239
+ expectProgram ( for: #"(a{,5})*"# , contains: [ . moveCurrentPosition, . condBranchSamePosition] )
240
+ expectProgram ( for: #"((\b){,4})*"# , contains: [ . moveCurrentPosition, . condBranchSamePosition] )
241
+ expectProgram ( for: #"((\b){1,4})*"# , contains: [ . moveCurrentPosition, . condBranchSamePosition] )
242
+ expectProgram ( for: #"((|){1,4})*"# , contains: [ . moveCurrentPosition, . condBranchSamePosition] )
243
+ // Inner node is a quantification that guarantees forward progress
244
+ expectProgram ( for: #"(a+)*"# , doesNotContain: [ . moveCurrentPosition, . condBranchSamePosition] )
245
+ expectProgram ( for: #"(a{1,})*"# , doesNotContain: [ . moveCurrentPosition, . condBranchSamePosition] )
246
+ }
211
247
}
0 commit comments