PPI

 view release on metacpan or  search on metacpan

lib/PPI/Lexer.pm  view on Meta::CPAN

			$self->_add_element( $Document, $Statement );
			$self->_lex_statement( $Statement );
			next;
		}

		# Is this the close of a structure.
		if ( $Token->__LEXER__closes ) {
			# Because we are at the top of the tree, this is an error.
			# This means either a mis-parsing, or a mistake in the code.
			# To handle this, we create a "Naked Close" statement
			$self->_add_element( $Document,
				PPI::Statement::UnmatchedBrace->new($Token)
			);
			next;
		}

		# Shouldn't be able to get here
		PPI::Exception->throw('Lexer reached an illegal state');
	}

	# Did we leave the main loop because of a Tokenizer error?
	unless ( defined $Token ) {
		my $errstr = $self->{Tokenizer} ? $self->{Tokenizer}->errstr : '';
		$errstr ||= 'Unknown Tokenizer Error';
		PPI::Exception->throw($errstr);
	}

	# No error, it's just the end of file.
	# Add any insignificant trailing tokens.
	$self->_add_delayed( $Document );

	# If the Tokenizer has any v6 blocks to attach, do so now.
	# Checking once at the end is faster than adding a special
	# case check for every statement parsed.
	my $perl6 = $self->{Tokenizer}->{'perl6'};
	if ( @$perl6 ) {
		my $includes = $Document->find( 'PPI::Statement::Include::Perl6' );
		foreach my $include ( @$includes ) {
			unless ( @$perl6 ) {
				PPI::Exception->throw('Failed to find a perl6 section');
			}
			$include->{perl6} = shift @$perl6;
		}
	}

	return 1;
}





#####################################################################
# Lex Methods - Statement Object

# Keyword -> Statement Subclass
my %STATEMENT_CLASSES = (
	# Things that affect the timing of execution
	'BEGIN'     => 'PPI::Statement::Scheduled',
	'CHECK'     => 'PPI::Statement::Scheduled',
	'UNITCHECK' => 'PPI::Statement::Scheduled',
	'INIT'      => 'PPI::Statement::Scheduled',
	'END'       => 'PPI::Statement::Scheduled',

	# Special subroutines for which 'sub' is optional
	'AUTOLOAD'  => 'PPI::Statement::Sub',
	'DESTROY'   => 'PPI::Statement::Sub',

	# Loading and context statement
	'package'   => 'PPI::Statement::Package',
	# 'use'       => 'PPI::Statement::Include',
	'no'        => 'PPI::Statement::Include',
	'require'   => 'PPI::Statement::Include',

	# Various declarations
	'my'        => 'PPI::Statement::Variable',
	'local'     => 'PPI::Statement::Variable',
	'our'       => 'PPI::Statement::Variable',
	'state'     => 'PPI::Statement::Variable',
	# Statements starting with 'sub' could be any one of...
	# 'sub'     => 'PPI::Statement::Sub',
	# 'sub'     => 'PPI::Statement::Scheduled',
	# 'sub'     => 'PPI::Statement',

	# Compound statement
	'if'        => 'PPI::Statement::Compound',
	'unless'    => 'PPI::Statement::Compound',
	'for'       => 'PPI::Statement::Compound',
	'foreach'   => 'PPI::Statement::Compound',
	'while'     => 'PPI::Statement::Compound',
	'until'     => 'PPI::Statement::Compound',

	# Switch statement
	'given'     => 'PPI::Statement::Given',
	'when'      => 'PPI::Statement::When',
	'default'   => 'PPI::Statement::When',

	# Various ways of breaking out of scope
	'redo'      => 'PPI::Statement::Break',
	'next'      => 'PPI::Statement::Break',
	'last'      => 'PPI::Statement::Break',
	'return'    => 'PPI::Statement::Break',
	'goto'      => 'PPI::Statement::Break',

	# Special sections of the file
	'__DATA__'  => 'PPI::Statement::Data',
	'__END__'   => 'PPI::Statement::End',
);

sub _statement {
	my ($self, $Parent, $Token) = @_;
	# my $self   = shift;
	# my $Parent = _INSTANCE(shift, 'PPI::Node')  or die "Bad param 1";
	# my $Token  = _INSTANCE(shift, 'PPI::Token') or die "Bad param 2";

	# Check for things like ( parent => ... )
	if (
		$Parent->isa('PPI::Structure::List')
		or
		$Parent->isa('PPI::Structure::Constructor')
	) {



( run in 0.620 second using v1.01-cache-2.11-cpan-39bf76dae61 )