Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Converting a source code

by oblate kramrdc (Acolyte)
on Aug 21, 2006 at 18:35 UTC ( [id://568639]=perlquestion: print w/replies, xml ) Need Help??

oblate kramrdc has asked for the wisdom of the Perl Monks concerning the following question:

Hello guys i'm trying to convert a source code to another and a friend of mine adviced me to use perl since it has powerful string manipulation. And so am learning pearl... Could anyone be kind enough to help me with this... When i run this there is no output saved in the target file... Thanks!



use strict; open sourcefile, "source.cbl" or die "Can't open: $!"; open targetfile, "source.ada" or die "Can't open: $!"; foreach my $line (<sourcefile>) { if ($line =~ /WORKING -STORAGE SECTION./) { print targetfile tr/WORKING -STORAGE SECTION./declare;/; } elsif ($line =~ /PROGRAM -BEGIN./) { print targetfile tr/PROGRAM -BEGIN./begin;/; } elsif ($line =~ /^DISPLAY/) { print targetfile tr/DISPLAY/PUT/; } elsif ($line =~ /^ACCEPT/) { print targetfile tr/ACCEPT/GET/; } elsif ($line =~ /PROGRAM -DONE./) { print targetfile tr/PROGRAM -DONE./END;/; } else { print "none"; } } close sourcefile or die "Can't close: $!";

Replies are listed 'Best First'.
Re: Converting a source code
by duckyd (Hermit) on Aug 21, 2006 at 18:54 UTC
    You need to open target file for writing, not reading.
    open targetfile, ">source.ada" or die "Can't open: $!";
    Consider using scalars for your filehandles. See open. Also, if you are not calling perl with -w, you should consider adding "use warnings;" in addition to use strict.

      Thanks duckyd! one more question... how do i store the value to targetfile? This doesn't work:

      s/WORKING -STORAGE SECTION./DECLARE;/; print targetfile $line, "\n";
      It stores "WORKING -STORAGE SECTION." tnx!

Re: Converting a source code
by swampyankee (Parson) on Aug 21, 2006 at 19:00 UTC

    One problem is this line:

    open targetfile, "source.ada" or die "Can't open: $!";
    By default Perl opens files for reading, not writing. Change the open for targetfile to this:
    open targetfile, ">", "source.ada" or die "Can't open: $!";
    ..and your output will go there.

    Another problem is that lines such as

    print targetfile tr/ACCEPT/GET/;

    will operate on the special variable $_, but the input is going to the variable $line.

    A third is that you want to use s///, not tr///; they behave quite differently. If I remember correctly, tr/PROGRAM -DONE./END;/ will replace every letter "P" with "E", letter "R" with "N", letter "O" with "D", and letter "G" with ";", and then cycle through "END;" as it runs into the letters "R", "A", "M", etc. This is probably not what you want (I'm thinking you want to change "PROGRAM -DONE." to "END;"; for that you'd need to use
    $line =~ s/PROGRAM -DONE./END;/;.

    I would suggest that you avoid the use of lowercase strings ("targetfile" or "sourcefile") for file handles; file handles are traditionally UPPERCASE. added in edit, see duckyd's post preceding this one or use scalar variables ($targetfile). Whether I use scalar variables or UPPERCASE strings for file handles depends on where they are in the code and where I expect to use the file handle.

    emc

    Experience is a hard teacher because she gives the test first, the lesson afterwards.

    Vernon Sanders Law
Re: Converting a source code
by GrandFather (Saint) on Aug 21, 2006 at 19:04 UTC

    tr translates characters. What you want to do is substitute strings. The strings you want to alter are stored in $line, but your current code, even if tr did as you expected, operates on $_ - the default variable.

    The foreach loop "slurps" the file - reads the whole thing into memory. Your current code doesn't require that - use a while loop instead.

    The following (untested) code should help:

    use strict; open sourcefile, '<', "source.cbl" or die "Can't open: $!"; open targetfile, '>', "source.ada" or die "Can't open: $!"; while (defined (my $line = <sourcefile>)) { if ($line =~ s/WORKING -STORAGE SECTION\./declare;/) { print targetfile $line; } elsif ($line =~ s/PROGRAM -BEGIN\./begin/) { print targetfile $line;

    However there are better ways of doing this trick. For a start you may be better putting your translation pairs into an array then itterate over it for each input line (untested):

    use strict; use warnings; my @pairs = ( ['WORKING -STORAGE SECTION.', 'declare'], ['PROGRAM -BEGIN.', 'begin;'], ['^DISPLAY', 'PUT'], ['^ACCEPT', 'GET'], ['PROGRAM -DONE.', 'END;'], ); open sourcefile, '<', "source.cbl" or die "Can't open: $!"; open targetfile, '>', "source.ada" or die "Can't open: $!"; while (defined (my $line = <sourcefile>)) { $line =~ s/$_-[0]/$_->[1]/ for @pairs; print targetfile $line; }

    However this sort of work is really crying out for Parse::RecDescent.

    Update change to three parameter opens.


    DWIM is Perl's answer to Gödel

      Thanks a lot monks! Been a big help! Combining all your comments...

      use strict; use warnings; open "SOURCEFILE", '<', "source.cbl" or die "Can't open: $!"; open "TARGETFILE", '>', "source.ada" or die "Can't open: $!"; while (defined (my $line = <SOURCEFILE>)) { if ($line =~ s/WORKING -STORAGE SECTION\./declare/) { print TARGETFILE $line; } elsif ($line =~ s/PROGRAM -BEGIN\./begin/) { print TARGETFILE $line; } elsif ($line =~ s/DISPLAY/PUT/) { print TARGETFILE $line; } elsif ($line =~ s/ACCEPT/GET/) { print TARGETFILE $line; } elsif ($line =~ s/PROGRAM -DONE\./END;/) { print TARGETFILE $line; } } close SOURCEFILE or die "Can't close: $!"; close TARGETFILE or die "Can't close: $!";
      Tried the array pairs GrandFather but i got a blank target file... I wonder why.... hmm.... <;

        You ought not have got a blank target file. However there was a bug in the code. $_-[0] in the regular expression should have been $_->[0].

        For test purposes it is conventient to use a __DATA__ section following the code and to print to the console. A test version of the code is:

        use strict; use warnings; my @pairs = ( ['WORKING -STORAGE SECTION.', 'declare'], ['PROGRAM -BEGIN.', 'begin;'], ['^DISPLAY', 'PUT'], ['^ACCEPT', 'GET'], ['PROGRAM -DONE.', 'END;'], ); while (defined (my $line = <DATA>)) { $line =~ s/$_->[0]/$_->[1]/ for @pairs; print $line; } __DATA__ WORKING -STORAGE SECTION. PROGRAM -BEGIN. DISPLAY ACCEPT PROGRAM -DONE. this DISPLAY not changed this ACCEPT not changed this PROGRAM -DONE. should get fixed

        Prints:

        declare begin; PUT GET END; this DISPLAY not changed this ACCEPT not changed this END; should get fixed

        DWIM is Perl's answer to Gödel

        No, no not this

        open "SOURCEFILE", '<', "source.cbl" or die "Can't open: $!";

        but this:
        open SOURCEFILE, '<', "source.cbl" or die "Can't open: $!";

        I probably was less than clear (typical; my first language is Ambiguous English). When I said "uppercase strings", I just meant that file handles typically look like this FILEHANDLE not like filehandle.

        emc

        Experience is a hard teacher because she gives the test first, the lesson afterwards.

        Vernon Sanders Law
        I hope the previous replies have solved the immediate problem for you, and you are getting stuff stored into your target file. Just a couple more comments about the code you posted:
        • If a line from the input file does not contain any of the patterns that you are altering via "s///", that line will not be printed to the output file. Is this what you want?
        • You are doing a lot of redundant typing. One of the nice things about Perl is that you can write scripts with an absolute minimum of repetitive lines of code.
        If you actually want the output file to have the same number of lines as the input file (with some lines being edited), it's pretty short and simple:
        use strict; use warnings; my $inp = "source.cbl"; my $out = "source.ada"; open INP, '<', $inp or die "Can't open $inp: $!"; open OUT, '>', $out or die "Can't open $out: $!"; while (<INP>) { s/WORKING -STORAGE SECTION\./declare/; s/PROGRAM -BEGIN\./begin/; s/DISPLAY/PUT/; s/ACCEPT/GET/; s/PROGRAM -DONE\./END;/; print OUT; } close INP; # no worries for closing input file close OUT or die "Can't close $out: $!";

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://568639]
Approved by GrandFather
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others exploiting the Monastery: (4)
As of 2024-04-25 12:23 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found