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]