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: ilya@schauder.mit.edu (Ilya Zakharevich) Subject: Re: Can I avoid using the "'" package syntax? Message-ID: <1993Dec15.012925.29596@galois.mit.edu> Sender: news@galois.mit.edu Nntp-Posting-Host: schauder Organization: MIT Department of Mathematics References: Date: Wed, 15 Dec 93 01:29:25 GMT Lines: 138 In article tchrist@cs.colorado.edu (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 = ; > $'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