pattern substitution question

J

james.herald

Hi. I'm writing a perl script to convert some fortran code to
IDL (at least, the statements which are easy to do). Here's
a type of conversion that I'm having trouble with:
I'd like to translate all FORTRAN like this:

dimension weight(4), xigau(4), xlim(5)

into this

weight = dblarr(4) && xigau = dblarr(4) && xlim = dblarr(5)

Here's what I have so far:
s/(dimension\s+)(\w+)(\(\d+\))/$1$2 \= dblarr$3/ig;
s/(dimension\s+.+?)(\,\s*)(\w+)(\(\d+\))/$1\&\& $3 \= dblarr$4/ig;
s/(dimension\s+)(\w+)/$2/ig;

which results in:
weight = dblarr(4)&& xigau = dblarr(4), xlim(5)
if I remove the "?" from the second statement, I get:
weight = dblarr(4), xigau(4)&& xlim = dblarr(5)

So, I'm having trouble coming up with an expression that does the
substitution for
multiple times on the same line. I could just repeat the 2nd statement
a few times,
but it seems there should be a way to do it automatically.

Any sed/awk hacks want to recommend something?

Thanks,

jim
 
X

Xicheng Jia

Hi. I'm writing a perl script to convert some fortran code to
IDL (at least, the statements which are easy to do). Here's
a type of conversion that I'm having trouble with:
I'd like to translate all FORTRAN like this:
=> dimension weight(4), xigau(4), xlim(5)
=> into this
=> weight = dblarr(4) && xigau = dblarr(4) && xlim = dblarr(5)

you can try this:

s/\G.*?(\w+)\((\d+)\)(,)?/$1 = dblarr($2)@{[ $3 and " && "]}/g;

or in another form:

s{ \G .*? (\w+) \( (\d+) \) (,)?
}{ "$1 = dblarr($2)". ( $3 and " && " ) }exg

1) use \G.*? to remove unnecessary characters.
2) if there is a comma then $3 is defined and print " && " to the
destination string...
3) you can also use @{[ ... ]} to insert perl code to replacement part
of the s/// expression, then you dont need the 'e' modifier.

Xicheng
 
J

John W. Krahn

Hi. I'm writing a perl script to convert some fortran code to
IDL (at least, the statements which are easy to do). Here's
a type of conversion that I'm having trouble with:
I'd like to translate all FORTRAN like this:

dimension weight(4), xigau(4), xlim(5)

into this

weight = dblarr(4) && xigau = dblarr(4) && xlim = dblarr(5)

$ perl -le'
$_ = q[dimension weight(4), xigau(4), xlim(5)];
print;
s{^dimension\s+(.+)}
{ (my $x = $1) =~ s<(\w+)(\(\d+\))><$1 = dblarr$2>g;
$x =~ s<, >< && >g;
$x }e;
print;
'
dimension weight(4), xigau(4), xlim(5)
weight = dblarr(4) && xigau = dblarr(4) && xlim = dblarr(5)



John
 
C

Charles DeRykus

Hi. I'm writing a perl script to convert some fortran code to
IDL (at least, the statements which are easy to do). Here's
a type of conversion that I'm having trouble with:
I'd like to translate all FORTRAN like this:

dimension weight(4), xigau(4), xlim(5)

into this

weight = dblarr(4) && xigau = dblarr(4) && xlim = dblarr(5)

Here's what I have so far:
s/(dimension\s+)(\w+)(\(\d+\))/$1$2 \= dblarr$3/ig;
s/(dimension\s+.+?)(\,\s*)(\w+)(\(\d+\))/$1\&\& $3 \= dblarr$4/ig;
s/(dimension\s+)(\w+)/$2/ig;

which results in:
weight = dblarr(4)&& xigau = dblarr(4), xlim(5)
if I remove the "?" from the second statement, I get:
weight = dblarr(4), xigau(4)&& xlim = dblarr(5)

So, I'm having trouble coming up with an expression that does the
substitution for
multiple times on the same line. I could just repeat the 2nd statement
a few times,
but it seems there should be a way to do it automatically.

Another possibility:

if ( /^dimension/g and my @vars = /\s+ (\S+) \((\d+)\) ,?/gx ) {
print $vars[$_], $_%2 ==0 ? " = " : do{$_==$#vars ? "\n" : " && "}
for 0 .. $#vars;
}
 
A

attn.steven.kuo

Hi. I'm writing a perl script to convert some fortran code to
IDL (at least, the statements which are easy to do). Here's
a type of conversion that I'm having trouble with:
I'd like to translate all FORTRAN like this:

dimension weight(4), xigau(4), xlim(5)

into this

weight = dblarr(4) && xigau = dblarr(4) && xlim = dblarr(5)

Here's what I have so far:

(snipped)

You may want to consider using a rule-based
parser like Parse::RecDescent:

use Parse::RecDescent

our @results;

my $grammer = <<'FIN';

dimension: "dimension" array(s /,/)

array: variable "(" length ")"
{ $return = "$item{variable} = dblarr($item{length})" }

variable: /\w+/

length: /\d+/

startrule: dimension
{ push @main::results, @item }

FIN

my $p = new Parse::RecDescent ( $grammer );

defined $p->startrule(
"dimension weight(4), xigau(4), xlim(5)"
) or die "Bad text\n";

print join ' && ' => @{$results[-1]};
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,045
Latest member
DRCM

Latest Threads

Top