Article 8895 of comp.lang.perl:
Xref: feenix.metronet.com comp.lang.perl:8895
Newsgroups: comp.lang.perl
Path: feenix.metronet.com!internet.spss.com!insosf1.infonet.net!news-feed-1.peachnet.edu!gatech!bloom-beacon.mit.edu!galois!schauder!ilya
From: [email protected] (Ilya Zakharevich)
Subject: Re: Can I avoid using the "'" package syntax?
Message-ID: <[email protected]>
Sender: [email protected]
Nntp-Posting-Host: schauder
Organization: MIT Department of Mathematics
References: <CHtxDv.795@da_vinci.it.uswc.uswest.com> <[email protected]>
Date: Wed, 15 Dec 93 01:29:25 GMT
Lines: 138

In article <[email protected]> [email protected] (Tom Christiansen) writes:
.....
>
> I wish it were easier for me to be sympathetic, but breaking, abusing, or
> avoiding an important language feature merely due to an overly ambitious
> and poorly implemented syntax directed editor seems to me to be clearly
> the wrong way to go.
>
> If you can't break yourself of the perl-mode habit, or fix it, then
> probably you shouldn't even try to use packages then.  But it'll bite you
> in other places:
>
> Think about all these:
>     s'foo'bar'g;
>     m#blech# if $x; # comment
>     tr"big"cat"d;
>     $a lt "bar"; @a = <foo 'bar' *.c>;
>     $'x;
>     $something'x;
>     $'; $`; $";
>     $main'';  # probably shouldn't work
>     <<'EOF';  # like ifdef notdef


Good time to advertize again the package that will automatically
comment complicated constructions:

#! /usr/local/bin/perl -p
#
#       comment_perl
#
# Problems with vgrind:
# package'variable, $', $", ticks inside s/// and m::, and \' &c.
# Since vgrind will (?) choke on \#, $#ARG or anything,
# we also recognize it as a comment
# I suppose that vgrind understands the pars '' ""  as not-inserted
# literals
# Since this converter inserts # '; at the end of the row, it can
# kill your program if you use it over the source file.
# We try to avoid this situation, and also the multiline literals killing,
# so we try to understand that the literals on the row are finished
# in the perlish sense. However, we use simplified algorithms, thus there
# no warranty that these algorithms will give some good answer.
# The main application of this script should be for PRETTY PRINTING,
# not for automatic modification of the code
# Since we do not recognize the difference between '' and plain text,
# something like '^.*\.exe$' will be misinterpreted, as a lot of other
# constructions.
# We do not try to recognize trickier s()()
# Skip if nothing to do
next unless /['"`]/ && /^\s*[^\s#]/;
$input = $_;        #   save for future reference
s/\\[^'"`#]//g;     #   remove control sequences
# Now we try to find when slash denotes m//
s@(^|(=|!)~?|\?|\(|\{|;|,|:|&|\||(^|\?|\(|\{|;|,|:|\s)(if|unless))\s*/@\1 m/@g;
s/\$\w+/\$a/g;      #   remove variables
#s/\w{2,}|[^\Wsm]/a/g;         #     not working :-{ (bug?) now we can use other letters than a s m
s/\w{3,}/a/g;       #     now we can use other letters than a s m
s/tr/s/g;       #     now we can use other letters than a s m
s/\w{2,}/a/g;       #     now we can use other letters than a s m
s/y/s/g;
s/\\'/t/g;          #   tick
s/\\`/b/g;          #   backtick
s/\\"/q/g;          #   quote
s/\$`/B/g;          #   backtick
s/\$"/Q/g;          #   quote
s/([\$\@\&\*a])'([\$a])/\1p\2/g;          #   package
s/\$'/T/g;          #   tick
#s:m([^\(\{\[])[^\1]*\1:m//:g;           # m// deletion : [^\1] should not work
                                                                                                                                                                # (waiting for ** in Perl 5)
#s:s([^\(\{\[])[^\1]*\1[^\1]*\1:s///:g;  # s// deletion
while (/m([^\(\{\[])/) {
       ($a=$1) =~ s/(\W)/\\\1/;
       eval "s:m$a:M$a: unless s:m$a[^$a]*$a:M//:g;";
}
while (/s([^\(\{\[])/) {
       ($a=$1) =~ s/(\W)/\\\1/;
       eval "s:s$a:S$a: unless s:s$a[^$a]*$a[^$a]*$a:S///:g;";
}

# Now we can recognize perlish interpretation of
# the pattern of "'`. If the string does not contain
# the balanced parts before and after the first comment '#' we refuse to
# work over it since we do not know what it should mean
# This will work if vgrind does not recognize inserted literals
# This won't work because of [^\3] (waiting for ** in Perl 5)
#$_=$input, next unless
#  /^([^#'"`]*((['"`])[^\3]*\3[^'"`#]*)*)(#[^'"`]*((['"`])[^\6]*\6[^'"`]*)*)?$/;
# "command" part $1
#$_=$1;
#$semi = /;\s*$/ ? ";" : "";
$comment=0;
$bad=0;
PERL_COMMENT:
while (/["'`#]|$/) {
       $_=$';
       if ($& eq "#" || $& eq "") {
               next if $comment==1 && $& eq "#";
               last if $comment==1 && $& eq "";
               $comment=1 unless $& eq "";
               $semi=($` =~ /;\s*$/) ? ";" : "";
               last if $comment==0;
 }
       else {($a=$&) =~ s/(\W)/\\\1/;
               eval "s/^[^$a]*$a// || (\$bad=1, last PERL_COMMENT);";
       }
}
$_=$input;
next if $bad;
# Now we can work safely over the vgindish interpretation
# Won't work because of [^\3] (waiting for ** in Perl 5)
#/^([^#'"`]*((['"`])[^\3]*\3[^'"`#]*)*([^#]*))(#|$)/;
# find if it is unbalanced
#next unless $4;
# Find the first occurrence of '"` - it will be marked by vgrind
#$liter=substr($4,0,1);
s/\\['"]//g;
$liter="";
V_COMMENT:
while (/["'#]/) {
       $_=$';
       $_=$input, last if ($& eq "#");
       ($a=$b=$&) =~ s/(\W)/\\\1/;    # =~ is evaluated on $a
 eval "s/^[^$a]*$a// || (\$liter=\$b, last V_COMMENT);";
}
$_=$input;
# find if it is unbalanced
next unless $liter;
# Now we know we should correct it
chop $input;
$_="$input\t# $liter$semi\n";
#
__END__

Ilya