Well, I was able to do more than I thought. When I apply the attached patches to the PPIx-Regexp distribution and install it, I get what I understand to be the desired behavior.
OK, only PPIx-Regexp-Token-Interpolate.patch is needed to fix the problem. The other adds a test of the new behavior.
Would you mind giving this a try and see if it does what you want? I still don't see how I can actually upload something to PAUSE until the end of next week.
--- lib/PPIx/Regexp/Token/Interpolation.old 2015-03-20 12:44:52.000000000 -0400
+++ lib/PPIx/Regexp/Token/Interpolation.pm 2015-03-20 12:42:52.000000000 -0400
@@ -89,7 +89,7 @@
# Match the beginning of an interpolation.
my $interp_re =
- qr{ \A (?: [\@\$]? \$ [-\w&`'+^./\\";%=~:?!\@\$<>\[\]\{\},#] |
+ qr{ \A (?= [\@\$]? \$ [-\w&`'+^./\\";%=~:?!\@\$<>\[\]\{\},#] |
\@ [\w\{] )
}smx;
@@ -123,7 +123,7 @@
}
# Make sure we start off plausibly
- $tokenizer->find_regexp( $interp_re )
+ defined $tokenizer->find_regexp( $interp_re )
or return;
# See if PPI can figure out what we have
@@ -280,11 +280,17 @@
and return 1;
}
- # If we have exactly one child which is a symbol, we accept it as a
- # subscript.
- @kids == 1
- and $kids[0]->isa( 'PPI::Token::Symbol' )
- and return 1;
+ # If the first child is a symbol,
+ if ( @kids && $kids[0]->isa( 'PPI::Token::Symbol' ) ) {
+ # Accept it if it is the only child
+ @kids == 1
+ and return 1;
+ # Accept it if there are exactly two children and the second is
+ # a subscript.
+ @kids == 2
+ and $kids[1]->isa( 'PPI::Structure::Subscript' )
+ and return 1;
+ }
# We reject anything else.
return;
--- t/unit.old 2015-03-09 14:04:58.000000000 -0400
+++ t/unit.t 2015-03-20 12:50:07.000000000 -0400
@@ -37,6 +37,24 @@
value ( max_capture_number => [], undef );
value ( source => [], 'fubar' );
+tokenize( '/$x{$y{z}}/' );
+count ( 5 );
+choose ( 0 );
+class ( 'PPIx::Regexp::Token::Structure' );
+content ( '' );
+choose ( 1 );
+class ( 'PPIx::Regexp::Token::Delimiter' );
+content ( '/' );
+choose ( 2 );
+class ( 'PPIx::Regexp::Token::Interpolation' );
+content ( '$x{$y{z}}' );
+choose ( 3 );
+class ( 'PPIx::Regexp::Token::Delimiter' );
+content ( '/' );
+choose ( 4 );
+class ( 'PPIx::Regexp::Token::Modifier' );
+content ( '' );
+
{
# The navigation tests get done in their own local scope so that all