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

I'm trying to convert a series of strings

MOVE 4 TO INT1.
DISPLAY 'MEMBERS OF THE GROUP'.
DISPLAY INT1.

to

INT1 := 4;
PUT("MEMBERS OF THE GROUP : ");
PUT(INT1);

I used this codes:

use strict; use warnings; my $SOURCEFILE; my $TARGETFILE; my $REPORTFILE; my $converted; my $discarded; my $holder; print "Enter filename to convert: "; chomp($SOURCEFILE = <STDIN>); print "Save to:"; chomp($TARGETFILE =<STDIN>); print "Save Conversion Report to:"; chomp($REPORTFILE =<STDIN>); open SOURCEFILE, '<', $SOURCEFILE or die "Can't open $SOURCEFILE: $!"; open TARGETFILE, '>', $TARGETFILE or die "Can't open $TARGETFILE: $!"; open REPORTFILE, '>', $REPORTFILE or die "Can't open $REPORTFILE: $!"; $converted=0; $discarded=0; sub reporting { print TARGETFILE $holder; print REPORTFILE " -> "; print REPORTFILE $holder; $converted++; } foreach my $line (<SOURCEFILE>) { if($line =~ /\bDISPLAY\s'([^']*)'\./) { $line = "PUT(\"$1\");\n"; $holder = $line; reporting; } elsif ($line =~ /\bMOVE/) { print REPORTFILE $line; $line =~ m/MOVE (\d+) TO ([\d\w]+)/; print TARGETFILE "$2 := $1;\n"; print REPORTFILE " -> "; print REPORTFILE "$2 := $1;\n"; $converted++; } else { $discarded++; print REPORTFILE "<xx> "; print REPORTFILE $line; } } print REPORTFILE "No. of Keywords Converted: "; print REPORTFILE $converted, "\n"; print REPORTFILE "No. of Keywords Discarded: "; print REPORTFILE $discarded, "\n"; close SOURCEFILE or die "Can't close: $!"; close TARGETFILE or die "Can't close: $!"; close REPORTFILE or die "Can't close: $!";
The problem is:

1. How do I switch the position of INT and 4?
2.And how do I replace the TO to :=
3. After the the DISPLAY ' was changed to PUT(". How do I change the '. at the end of the sentence to ");

I'm still learning PERL your inputs are really appreciated!
Thanks in advance!

Edited by planetscape - added readmore tags

( keep:3 edit:24 reap:0 )

Replies are listed 'Best First'.
Re: switching parts of a text
by Tanktalus (Canon) on Sep 14, 2006 at 21:04 UTC

    What you probably want is something using Parse::RecDescent. But that's beyond my skill, so if you're claiming to be "still learning PERL" then it may not be what you want, either. Or, if it is, I can't help ;-)

    You may want to make a few changes, and learn a bit more about the substitution operator in perlre. For example, instead of doing this in a huge if/elsif block, you can take advantage of the fact that if the s operator doesn't find the first regular expression in the line, it won't do anything. And it will return false.

    s/^\s*MOVE\s+(\S+)\s+TO\s+(\S+)\s*\./$2 := $1;/ and next; s/^\s*DISPLAY\s+'(.*)'\./PUT("$1")/ and next; s/^\s*DISPLAY\s+(.*)\./PUT($1)/ and next; ++$discarded;
    Note that I do the check with the quote before the check without the quote - because the one without the quote will match with quotes, too.

    Hope that helps,

    Update: The above merely changes the value in-place. You'll need to copy the value to your output. It's easier if you don't care about the discarded bit ;-)

      WOW!
      That was short! Thanks Tanktalus!

Re: switching parts of a text
by GrandFather (Saint) on Sep 14, 2006 at 21:26 UTC

    Apart from reworking your code a little to avoid external file usage, the following should point you in the right direction:

    use strict; use warnings; my $converted; my $discarded; my $holder; my @report; $converted=0; $discarded=0; sub report { my ($original, $result) = @_; $original =~ tr/\n//d; if (defined $result) { $result =~ tr/\n//d; push @report, "$original -> $result\n"; $converted++; } else { push @report, "$original\n"; } } while (<DATA>) { my $line = $_; if ($line =~ /\bMOVE\s(\d+)\sTO\s(\w+)/) { $line = "$2 := $1;\n"; report ($_, $line); } elsif ($line =~ /\bDISPLAY\s'([^']*)'\./) { $line = "PUT(\"$1\");\n"; report ($_, $line); } elsif ($line =~ /\bDISPLAY\s(\w+)\./) { $line = "PUT($1);\n"; report ($_, $line); } else { $discarded++; } print $line; } report ("No. of Keywords Converted: $converted\n"); report ("No. of Keywords Discarded: $discarded, \n"); print "------------------8<----------------------\n"; print @report; __DATA__ MOVE 4 TO INT1. DISPLAY 'MEMBERS OF THE GROUP'. DISPLAY INT1. ADD 5 TO INT4

    Prints:

    INT1 := 4; PUT("MEMBERS OF THE GROUP"); PUT(INT1); ADD 5 TO INT4 ------------------8<---------------------- MOVE 4 TO INT1. -> INT1 := 4; DISPLAY 'MEMBERS OF THE GROUP'. -> PUT("MEMBERS OF THE GROUP"); DISPLAY INT1. -> PUT(INT1); No. of Keywords Converted: 3 No. of Keywords Discarded: 1,

    DWIM is Perl's answer to Gödel

      Thanks very much for your help GrandFather!

Re: switching parts of a text
by hgolden (Pilgrim) on Sep 14, 2006 at 20:58 UTC
    Hey,

    When you match the move strings, you can capture the information you need with a regular expression. If the string will always be like what you show, then this could be:

    m/MOVE (\d+) TO ([\d\w]+)/
    and then the line you want will be  print WHATEVER "$2 := $1", since the first thing in paratheses goes into $1 and the second thing into $2. With some tuning up, that should cover your first two concerns.

    For the last one, if there won't be any other single-quotes, you could just perform a substitution. If you're expecting them in the strings, then you can do a substitution which includes the end of string character: $. That way, you'll only match the final single-quote. I hope this helps.

    Hays