]> git.donarmstrong.com Git - perltidy.git/commitdiff
Fix error parsing '%#' and similar combinations
authorSteve Hancock <perltidy@users.sourceforge.net>
Wed, 7 Jul 2021 00:42:48 +0000 (17:42 -0700)
committerSteve Hancock <perltidy@users.sourceforge.net>
Wed, 7 Jul 2021 00:42:48 +0000 (17:42 -0700)
lib/Perl/Tidy/Tokenizer.pm
local-docs/BugLog.pod

index 99b0a9198902e382b29db645f351221a5484ac79..0c22408300dd4826983feef59f43e3357931e71d 100644 (file)
@@ -2580,7 +2580,10 @@ EOM
         '*' => sub {    # typeglob, or multiply?
 
             if ( $expecting == UNKNOWN && $last_nonblank_type eq 'Z' ) {
-                if ( $next_type ne 'b' && $next_type ne '(' ) {
+                if (   $next_type ne 'b'
+                    && $next_type ne '('
+                    && $next_type ne '#' )    # Fix c036
+                {
                     $expecting = TERM;
                 }
             }
@@ -6818,30 +6821,39 @@ sub scan_identifier_do {
                 #  howdy::123::bubba();
                 #
             }
+            elsif ( $tok eq '#' ) {
 
-            # $# and POSTDEFREF ->$#
-            elsif (
-                   ( $tok eq '#' )
-                && ( $identifier =~ /\$$/ )
+                # side comment or identifier?
+                if (
 
-                # a # inside a prototype or signature can only start a comment
-                && !$in_prototype_or_signature
-              )
-            {
-                # A '#' starts a comment if it follows a space. For example,
-                # the following is equivalent to $ans=40.
-                #   my $ #
-                #     ans = 40;
-                if ($last_tok_is_blank) {
-                    $type = 'i';
-                    if ( $id_scan_state eq '$' ) { $type = 't' }
+                    # A '#' starts a comment if it follows a space. For example,
+                    # the following is equivalent to $ans=40.
+                    #   my $ #
+                    #     ans = 40;
+                    !$last_tok_is_blank
+
+                    # a # inside a prototype or signature can only start a
+                    # comment
+                    && !$in_prototype_or_signature
+
+                    # these are valid punctuation vars: *# %# @# $#
+                    # May also be '$#array' or POSTDEFREF ->$#
+                    && ( $identifier =~ /^[\%\@\$\*]$/ || $identifier =~ /\$$/ )
+
+                  )
+                {
+                    $identifier .= $tok;    # keep same state, a $ could follow
+                }
+                else {
+
+                    # otherwise it is a side comment
+                    if    ( $identifier eq '->' )   { }
+                    elsif ( $id_scan_state eq '$' ) { $type = 't' }
+                    else                            { $type = 'i' }
                     $i             = $i_save;
                     $id_scan_state = '';
                     last;
                 }
-
-                # May be '$#' or '$#array'
-                $identifier .= $tok;    # keep same state, a $ could follow
             }
 
             elsif ( $tok eq '{' ) {
index 4703e7fe6f621b34e8635953d7e64d25ed85b4e4..c34d60a2f3bdac4ab8c92e8dbf0282c51a58ee6e 100644 (file)
@@ -2,6 +2,35 @@
 
 =over 4
 
+=item B<Fix error parsing '%#' and similar combinations>
+
+Perltidy was correctly distinguishing between '$#' and '$ #' but not between
+'@#' and '@ #' and '%#' and '% #'.  The coding for parsing these types of
+expressions has been corrected. Some simple examples:
+
+    # this is a valid program, '%#' is a punctuation variable
+    %# = ( foo => 'bar', baz => 'buz' );
+    print keys(%#), "\n";
+
+    # but this is a syntax error (space before # makes a side comment)
+    # (perltidy was ignoring the space and forming '%#' here)
+    % # = ( foo => 'bar', baz => 'buz' );
+    print keys(%#), "\n";
+
+    # this is a valid program, '@#' is a punctuation variable
+    @# = ( foo , 'bar', baz , 'buz' );
+    print @#, "\n";
+
+    # this is a valid program, the space makes the '#' a side comment
+    # perltidy formed %# here, causing an error
+    % #
+    var = ( foo => 'bar', baz => 'buz' );
+    print keys(%var), "\n";
+
+This fixes case c036.
+
+6 Jul 2021.
+
 =item B<Fix error parsing '&#'>
 
 The following test script caused an error when perltidy did not correctly parse