Summary
Recursive subroutine calls ((?1), (?R)) are partially implemented but fail to track capturing group values correctly during recursion. Palindrome-style recursive patterns are entirely broken.
Failing PCRE Tests (Category 3 — 9 tests)
^((.)(?1)\2|.?)$ — palindrome; should match abba, ababa, abccba
^(.|(.)(?1)\2)$ — should match aba, abcba, ababa
^(.|(.)(?1)?\2)$ — should match abcba
^(a?)+b(?1)a — should match aba, ba
^(a?)b(?1)a — should match aba
Expected gain: +9 PCRE conformance tests
Root Cause
RecursiveDescentBytecodeGenerator saves/restores group slots during subroutine calls but does not support backtracking within those recursive calls. Palindrome patterns require the recursive call to try both branches of the alternation and unwind on failure, which needs backtrackable subroutines.
Implementation Notes
- Tracked in
doc/plans/pcre-conformance-roadmap.md as Phase 3, item 3.2
- Difficulty: High (estimated 8–12 hours)
- Tests are skipped by default; run with
-Dreggie.test.knownFailures=true
- File:
RecursiveDescentBytecodeGenerator.java
Summary
Recursive subroutine calls (
(?1),(?R)) are partially implemented but fail to track capturing group values correctly during recursion. Palindrome-style recursive patterns are entirely broken.Failing PCRE Tests (Category 3 — 9 tests)
^((.)(?1)\2|.?)$— palindrome; should matchabba,ababa,abccba^(.|(.)(?1)\2)$— should matchaba,abcba,ababa^(.|(.)(?1)?\2)$— should matchabcba^(a?)+b(?1)a— should matchaba,ba^(a?)b(?1)a— should matchabaExpected gain: +9 PCRE conformance tests
Root Cause
RecursiveDescentBytecodeGeneratorsaves/restores group slots during subroutine calls but does not support backtracking within those recursive calls. Palindrome patterns require the recursive call to try both branches of the alternation and unwind on failure, which needs backtrackable subroutines.Implementation Notes
doc/plans/pcre-conformance-roadmap.mdas Phase 3, item 3.2-Dreggie.test.knownFailures=trueRecursiveDescentBytecodeGenerator.java