use warnings; use strict; use constant DENT => ' '; our $parens; my $text = do { local $/; }; sub parse { my ($text, $indent) = @_; $indent = 0 unless defined $indent; local $parens = qr{ (?: [^{}]+? | \{ (??{$parens}) \} )* }xms; while ($text =~ /module \s+ (\w+) \s* \{ ($parens) \} ;? /gx) { my ($name, $content) = ($1, $2); print DENT x $indent, qq(subgraph $name { \n); ++$indent; parse($content, $indent); print DENT x $indent, qq(} \n); --$indent; } } # print $text; # FOR DEBUG print "digraph G\n{\n"; parse($text); print "}\n"; __DATA__ module abc { module def { module ghi { module jkl {} }; }; }; #### digraph G { subgraph abc { subgraph def { subgraph ghi { subgraph jkl { } } } } }