perl5 icon indicating copy to clipboard operation
perl5 copied to clipboard

(*THEN) re-enables matching attempts after (*PRUNE) was in effect

Open rsFalse opened this issue 1 year ago • 1 comments

Description

https://perldoc.perl.org/perlre#Special-Backtracking-Control-Verbs

When found on backtracking (*PRUNE) should fail the whole match and start a new attempt from the next character. But when (*THEN) verb is found, it restores matching attempts. Similarly (*SKIP) is also affected.

Steps to Reproduce

#!/usr/bin/perl -wl

use strict;

my @control_verbs = map "(*$_)", ( 
	'THEN',
	'PRUNE',
#	'SKIP',
	);

unshift @control_verbs, '';

my $case = 0;

for my $i ( @control_verbs ){
	for my $j ( @control_verbs ){
		$case ++;
		print "---case $case:[$i][$j]---";
		"aaaAAA" =~ m/^
			(  a++ (?{ print "1a++"})
			   $i
			 | aaa (?{ print "1aaa"})
			)
			(  A++ (?{ print "2A++"})
			   $j
			 | AAA (?{ print "2AAA"})
			)$ 
			(?{ print "[$&]" })
			(*F)
			/x;
		}
	}

Output cases:

---case 1:[][]---
1a++
2A++
[aaaAAA]
2AAA
[aaaAAA]
1aaa
2A++
[aaaAAA]
2AAA
[aaaAAA]
---case 2:[][(*THEN)]---
1a++
2A++
[aaaAAA]
2AAA
[aaaAAA]
1aaa
2A++
[aaaAAA]
2AAA
[aaaAAA]
---case 3:[][(*PRUNE)]---
1a++
2A++
[aaaAAA]
---case 4:[(*THEN)][]---
1a++
2A++
[aaaAAA]
2AAA
[aaaAAA]
1aaa
2A++
[aaaAAA]
2AAA
[aaaAAA]
---case 5:[(*THEN)][(*THEN)]---
1a++
2A++
[aaaAAA]
2AAA
[aaaAAA]
1aaa
2A++
[aaaAAA]
2AAA
[aaaAAA]
---case 6:[(*THEN)][(*PRUNE)]---
1a++
2A++
[aaaAAA]
2AAA
[aaaAAA]
1aaa
2AAA
[aaaAAA]
---case 7:[(*PRUNE)][]---
1a++
2A++
[aaaAAA]
2AAA
[aaaAAA]
---case 8:[(*PRUNE)][(*THEN)]---
1a++
2A++
[aaaAAA]
2AAA
[aaaAAA]
1aaa
2AAA
[aaaAAA]
---case 9:[(*PRUNE)][(*PRUNE)]---
1a++
2A++
[aaaAAA]

Cases 1, 2, 4, 5 outputs the same. Cases 3 and 9 outputs the same. Both as expected, 7th also as expected.

---case 1:[][]---
---case 2:[][(*THEN)]---
---case 4:[(*THEN)][]---
---case 5:[(*THEN)][(*THEN)]---

---case 3:[][(*PRUNE)]---
---case 9:[(*PRUNE)][(*PRUNE)]---

---case 7:[(*PRUNE)][]---

6th and 8th seems unexpected.

---case 6:[(*THEN)][(*PRUNE)]---
---case 8:[(*PRUNE)][(*THEN)]---

Expected behavior

Case 6 expected to output the same as cases 3 and 9. Case 8 expected to output:

1a++
2A++
[aaaAAA]
2AAA
[aaaAAA]

Perl configuration

This is perl 5, version 38, subversion 2 (v5.38.2) built for x86_64-linux

rsFalse avatar Dec 26 '23 21:12 rsFalse

FYI, having inspected this on older perls, this behaviour doesn't seem to have changed since at least 5.30, maybe even older.

leonerd avatar Mar 14 '24 17:03 leonerd