PHP-Decode
view release on metacpan or search on metacpan
lib/PHP/Decode/Parser.pm view on Meta::CPAN
#
# parse PHP source files
#
package PHP::Decode::Parser;
use base 'PHP::Decode::Tokenizer';
use strict;
use warnings;
use Carp 'croak';
use Config;
use PHP::Decode::Array qw(is_int_index);
use Exporter qw(import);
our @EXPORT_OK = qw(is_variable is_symbol is_null is_const is_numval is_strval is_array is_block global_var global_split inst_var inst_split method_name method_split ns_name ns_split);
our %EXPORT_TAGS = (all => \@EXPORT_OK);
our $VERSION = '0.127';
# avoid 'Deep recursion' warnings for depth > 100
#
no warnings 'recursion';
my $stridx = 1;
my $numidx = 1;
my $constidx = 1;
my $funidx = 1;
my $callidx = 1;
my $elemidx = 1;
my $expridx = 1;
my $stmtidx = 1;
my $blkidx = 1;
my $pfxidx = 1;
my $objidx = 1; # obj->
my $scopeidx = 1; # class::
my $refidx = 1; # & $var
my $classidx = 1; # class name {}
my $instidx = 1; # class instance
my $traitidx = 1; # trait name {}
my $nsidx = 1; # namespace\
my $fhidx = 1;
# Initialize new parser using PHP::Decode::Tokenizer
# {inscript} - set to indicate already inside of script
# {warn} - warning message handler
# {log} - log message handler
# {debug} - debug message handler
# {filename} - optional filename (if not stdin or textstr)
# {max_strlen} - max strlen for debug strings
#
sub new {
my ($class, %args) = @_;
my $strmap = $args{strmap} or croak __PACKAGE__ . " expects strmap";
my $self = $class->SUPER::new(%args);
$self->{max_strlen} = 0 unless exists $self->{max_strlen};
$self->{tok} = []; # init token list
# filename is required to decode __FILE__
$self->{filename} = '__FILE__' unless exists $self->{filename};
$strmap->{'__LINE__'} = 1 unless exists $strmap->{'__LINE__'};
$strmap->{'#null'} = '' unless exists $strmap->{'#null'};
return $self;
}
# A sub parser is always inscript (the parent might have inscript=0)
#
sub subparser {
my ($self, %args) = @_;
my $parser = PHP::Decode::Parser->new(strmap => $self->{strmap}, inscript => 1, filename => $self->{filename}, max_strlen => $self->{max_strlen}, warn => $self->{warn});
$parser->{log} = $self->{log} if exists $self->{log};
$parser->{debug} = $self->{debug} if exists $self->{debug};
foreach my $k (keys %args) {
lib/PHP/Decode/Parser.pm view on Meta::CPAN
# check if statement is empty block
#
sub is_empty_block {
my ($self, $s) = @_;
if (is_block($s)) {
my ($type, $a) = @{$self->{strmap}->{$s}};
if (scalar @$a == 0) {
return 1;
}
}
return 0;
}
# flatten block (and remove #null statements)
#
sub flatten_block {
my ($self, $s, $out) = @_;
if (is_block($s)) {
my ($type, $a) = @{$self->{strmap}{$s}};
foreach my $stmt (@$a) {
$self->flatten_block($stmt, $out);
}
} else {
if ($s ne '#null') {
push(@$out, $s);
}
}
return;
}
# flatten block with single statement
#
sub flatten_block_if_single {
my ($self, $s) = @_;
if (is_block($s)) {
my ($type, $a) = @{$self->{strmap}{$s}};
if (scalar @$a == 1) {
return $a->[0];
}
}
return $s;
}
# create and split global var
#
sub global_var {
my ($global) = @_;
return '$GLOBALS' . $global;
}
sub global_split {
my ($var) = @_;
my ($global) = $var =~ /^\$GLOBALS(\$.*)$/;
return $global;
}
# create and split method name
#
sub method_name {
my ($class, $name) = @_;
return $class . '::' . $name;
}
sub method_split {
my ($method) = @_;
# allow namespace prefix
my ($class, $name) = $method =~ /^(#inst\d+|[\w\x80-\xff\\]+)::([\w\x80-\xff]+)$/;
return ($class, $name);
}
# create and split instance var
#
sub inst_var {
my ($inst, $var) = @_;
return '$' . $inst . $var;
}
sub inst_split {
my ($instvar) = @_;
my ($inst, $var) = $instvar =~ /^\$(#inst\d+|[\w\x80-\xff]+)(\$.*)$/;
return ($inst, $var);
}
# create and split namespace name
#
sub ns_name {
my ($name, $elem) = @_;
return $name . '\\' . $elem;
}
sub ns_split {
my ($name) = @_;
my ($ns, $elem) = $name =~ /^([^\\]*)\\(.+)$/;
return ($ns, $elem);
}
# create path from namespace
#
sub ns_to_str {
my ($self, $var) = @_;
if ($var =~ /^#ns\d+$/) {
my ($n, $e) = @{$self->{strmap}{$var}};
unless (defined $n) {
$n = ''; # toplevel
}
$e = $self->ns_to_str($e);
if (defined $e) {
return ns_name($n, $e);
}
} elsif (is_strval($var)) {
return $self->{strmap}{$var};
} else {
return $var;
}
return;
( run in 0.622 second using v1.01-cache-2.11-cpan-71847e10f99 )