#!/usr/bin/perl use strict; use warnings; use PPI; use PPI::Dumper; my $file = shift @ARGV; my $doc = PPI::Document->new($file) or die "Could not open file: $!"; parse_package($doc); print " O\n"; sub parse_package { # find out the package name, if none, assume main. my $tree = shift; my $packages = $tree->find_first('PPI::Statement::Package'); if ($packages) { my $words = $packages->find('PPI::Token::Word'); print "[P] " . $$words[1] . "\n"; parse_includes($tree); print " |\n"; parse_subs($tree); print " |\n"; parse_shedules($tree); #parse_shedules()... } else { print "[P] main:\n"; parse_includes($tree); print " |\n"; parse_subs($tree); print " |\n"; parse_shedules($tree); # ... continue parsing. } } sub parse_includes { # parse use/require statements. my $tree = shift; my $includes = $tree->find('PPI::Statement::Include') or return; foreach my $include (@$includes) { #my $name = ${ $include->find('PPI::Token::Word') }[1]; print " `- [I] $include\n"; } } sub parse_subs { # parse subroutines. my $tree = shift; my $subs = $tree->find('PPI::Statement::Sub') or return; foreach my $sub (@$subs) { next if $sub->isa('PPI::Statement::Scheduled'); my $subroutine_name = ${ $sub->find('PPI::Token::Word') }[1]; my $subroutine_prototype = $sub->find_first('PPI::Token::Prototype'); my $comment = parse_comment($sub); print " `- [S] $subroutine_name $subroutine_prototype\t$comment\n"; parse_variables($sub); } } sub parse_shedules { # parse BEGIN/END/INITCHECK blocks etc. my $tree = shift; my $subs = $tree->find('PPI::Statement::Scheduled') or return; foreach my $sub (@$subs) { my $blockname = $sub->find_first('PPI::Token::Word'); print " `- [B] $blockname\n"; parse_variables($sub); } } sub parse_variables { # parse variables from any subset of the tree. my $tree = shift; my $declarations = $tree->find('PPI::Statement::Variable') or return; foreach my $declaration ( @{$declarations} ) { my $type_of_declaration = $declaration->find_first('PPI::Token::Word'); my $variable_name = $declaration->find_first('PPI::Token::Symbol'); print " | `- [D] $type_of_declaration $variable_name\n"; } } sub parse_comment { # prints the first comment in some subset of the tree. my $tree = shift; my $comment = $tree->find_first('PPI::Token::Comment') or return ""; return $comment->content(); }