thanks a lot. I'll try. :)

--- "Beau E. Cox" <[EMAIL PROTECTED]> wrote:
> Hi Tao,
> > -----Original Message-----
> > From: tao wang [mailto:[EMAIL PROTECTED]
> > Sent: Saturday, March 01, 2003 9:49 AM
> > To: [EMAIL PROTECTED]
> > Subject: how to detect a circular macro by using
> perl
> > 
> > 
> > Hi Everyone,
> >   I'm trying to parse lines of macros definitions
> as
> > following:
> > 
> > AV   $(G)/er $(M)/q $(T)/w/f
> > G    ter/eee
> > M    $(W)
> > T    g/ee/fet
> > W    $(AV)
> > 
> > You can see the AV is actually a circular macro
> since
> > the AV -> M -> W-> AV.  I'm think about create a
> tree
> > to do it.  Is it possible? and how can i do it? 
> Are
> > there any other ways to do it? thank a lot.  I
> really
> > appreciate it.                 - tao
> > 
> 
> This was a real brain teaser for me! I have put
> together
> a script that seems to work, but it's *neither*
> concise *nor*
> elegant. If you or anyone else has some nice
> solution,
> please post it! :)
> 
> My script:
> 
> #!/usr/bin/perl
> use strict;
> use warnings;
> 
> # sample input
> 
> my $input = <<'*EOF*';
> AV   $(G)/er $(M)/q $(T)/w/f
> G    ter/eee
> M    $(W)
> T    g/ee/fet
> W    $(AV)
> *EOF*
> 
> # parse input into a hash having key == macro name
> # and value == hash (ref) of dependent macro names
> 
>       my %macros;
>       my @lines = split /\n/, $input;
>       for (@lines) {
>               my ($name, $value) = /^(\w+)\s+(.*)/;
>               next unless $name and $value;
>               my (@macs) = /\$\((\w+)\)/g;
>               $macros{$name}->{$_} = 1 for (@macs);
>               }
> 
> # print (for debugging)
> 
>       print "input:\n";
>       for (sort keys %macros) {
>               print "$_:";
>               for my $mac (sort keys %{$macros{$_}}) {
>                       print " -> $mac";
>                       }
>               print "\n";
>               }
> 
> # iterate thru hash finding circular dependences
> 
>       print "expand:\n";
>       my $cir_count = 0;
>       for (sort keys %macros) {
>               my $def = "$_:";
>               $cir_count += expand (\$def, $_, $macros{$_});
>               print "$def\n";
>               }
>       print "$cir_count circular definitions\n";
> 
> # recursive expand and check circular routine
> 
> sub expand
> {
>       my ($def, $name, $mhash) = @_;
>       return 0 unless $mhash;
>       for my $mac (sort keys %{$mhash}) {
>               $$def .= " -> $mac";
>               if ($mac eq $name) {
>                       $$def .= " *CIRCULAR*";
>                       return 1;
>                       }
>               return 1 if expand ($def, $name, $macros{$mac});
>               }
>       return 0;
> }
> 
> output:
> 
> input:
> AV: -> G -> M -> T
> M: -> W
> W: -> AV
> expand:
> AV: -> G -> M -> W -> AV *CIRCULAR*
> M: -> W -> AV -> G -> M *CIRCULAR*
> W: -> AV -> G -> M -> W *CIRCULAR*
> 3 circular definitions
> 
> Note: I am correct in that AV, M, and W are circular
> (not just AV) am I not?
> 
> Notice that I have not captured the 'guts' of each
> macro,
> just calls to other macros. The parsing may have to
> be
> adjusted to suit your purposes. The 'sort' of hashes
> in
> the script is optional, I used it simply to put
> the results in some kind of order; in your real
> script you
> probably should use array references to insure the
> expansion sequence is maintained.
> 
> Well, it's a poor, old, hacker's start at least...
> again,
> does anyone have a really slick solution?
> 
> Aloha => Beau;
> 
> 
> -- 
> To unsubscribe, e-mail:
> [EMAIL PROTECTED]
> For additional commands, e-mail:
> [EMAIL PROTECTED]
> 


__________________________________________________
Do you Yahoo!?
Yahoo! Tax Center - forms, calculators, tips, more
http://taxes.yahoo.com/

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to