PPI
view release on metacpan or search on metacpan
lib/PPI/Tokenizer.pm view on Meta::CPAN
of the token stream.
Return true if the cursor is decremented, C<0> if already at the
beginning of the file, or C<undef> on error.
=cut
sub decrement_cursor {
my $self = shift;
# Check for the beginning of the file
return 0 unless $self->{token_cursor};
# Decrement the token cursor
$self->{token_eof} = 0;
--$self->{token_cursor};
}
#####################################################################
# Working With Source
# Fetches the next line from the input line buffer
# Returns undef at EOF.
sub _get_line {
my $self = shift;
return undef unless $self->{source}; # EOF hit previously
# Pull off the next line
my $line = shift @{$self->{source}};
# Flag EOF if we hit it
$self->{source} = undef unless defined $line;
# Return the line (or EOF flag)
return $line; # string or undef
}
# Fetches the next line, ready to process
# Returns 1 on success
# Returns 0 on EOF
sub _fill_line {
my $self = shift;
my $inscan = shift;
# Get the next line
my $line = $self->_get_line;
unless ( defined $line ) {
# End of file
unless ( $inscan ) {
delete $self->{line};
delete $self->{line_cursor};
delete $self->{line_length};
return 0;
}
# In the scan version, just set the cursor to the end
# of the line, and the rest should just cascade out.
$self->{line_cursor} = $self->{line_length};
return 0;
}
# Populate the appropriate variables
$self->{line} = $line;
$self->{line_cursor} = -1;
$self->{line_length} = length $line;
$self->{line_count}++;
1;
}
# Get the current character
sub _char {
my $self = shift;
substr( $self->{line}, $self->{line_cursor}, 1 );
}
####################################################################
# Per line processing methods
# Processes the next line
# Returns 1 on success completion
# Returns 0 if EOF
# Returns undef on error
sub _process_next_line {
my $self = shift;
# Fill the line buffer
my $rv;
unless ( $rv = $self->_fill_line ) {
return undef unless defined $rv;
# End of file, finalize last token
$self->_finalize_token;
return 0;
}
# Run the __TOKENIZER__on_line_start
$rv = $self->{class}->__TOKENIZER__on_line_start( $self );
unless ( $rv ) {
# If there are no more source lines, then clean up
if ( ref $self->{source} eq 'ARRAY' and ! @{$self->{source}} ) {
$self->_clean_eof;
}
# Defined but false means next line
return 1 if defined $rv;
PPI::Exception->throw("Error at line $self->{line_count}");
}
# If we can't deal with the entire line, process char by char
while ( $rv = $self->_process_next_char ) {}
unless ( defined $rv ) {
PPI::Exception->throw("Error at line $self->{line_count}, character $self->{line_cursor}");
( run in 1.298 second using v1.01-cache-2.11-cpan-f56aa216473 )