@@ -208,4 +208,40 @@ extension RegexTests {
208208 expectProgram ( for: " [abc] " , semanticLevel: . unicodeScalar, doesNotContain: [ . matchBitset] )
209209 expectProgram ( for: " [abc] " , semanticLevel: . unicodeScalar, contains: [ . consumeBy] )
210210 }
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+ }
211247}
0 commit comments