NAME
Devel::Declare::Lexer - Easier than Devel::Declare
SYNOPSIS
# Add :debug tag to enable debugging
# Add :lexer_test to enable variable assignment
# Anything not starting with : becomes a keyword
use Devel::Declare::Lexer qw/ keyword /;
BEGIN {
# Create a callback for the keyword (inside a BEGIN block!)
Devel::Declare::Lexer::lexed(keyword => sub {
# Get the stream out (given as an arrayref)
my ($stream_r) = @_;
my @stream = @$stream_r;
my $str = $stream[2]; # in the example below, the string is the 3rd token
# Create a new stream (we could manipulate the existing one though)
my @ns = ();
tie @ns, "Devel::Declare::Lexer::Stream";
# Add a few tokens to print the string
push @ns, (
# You need this (for now)
new Devel::Declare::Lexer::Token::Declarator( value => 'keyword' ),
new Devel::Declare::Lexer::Token::Whitespace( value => ' ' ),
# Everything else is your own custom code
new Devel::Declare::Lexer::Token( value => 'print' ),
new Devel::Declare::Lexer::Token::Whitespace( value => ' ' ),
$string,
new Devel::Declare::Lexer::Token::EndOfStatement,
new Devel::Declare::Lexer::Token::Newline,
);
# Stream now contains:
# keyword and print "This is a string";
# keyword evaluates to 1, everything after the and gets executed
# Return an arrayref
return \@ns;
});
}
# Use the keyword anywhere in this package
keyword "This is a string";
DESCRIPTION
Devel::Declare::Lexer makes it easier to parse code using Devel::Declare by generating a token stream from the statement and providing a callback for you to manipulate it before its parsed by Perl.
The example in the synopsis creates a keyword named 'keyword', which accepts a string and prints it.
Although this simple example could be done using print, say or any other simple subroutine, Devel::Declare::Lexer supports much more flexible syntax.
For example, it could be used to auto-expand subroutine declarations, e.g. method MethodName ( $a, @b ) { ... } into sub MethodName ($@) { my ($self, $a, @b) = @_; ... }
Unlike Devel::Declare, there's no need to worry about parsing text and taking care of multiline strings or code blocks - it's all done for you.
ADVANCED USAGE
Devel::Declare::Lexer's standard behaviour is to inject a sub into the calling package which returns a 1. Because your statement typically gets transformed into something like keyword and [your statement here]; the fact keyword evaluates to 1 means everything following the and will always be executed.
You can extend this by using a different import syntax when loading Devel::Declare::Lexer use Devel::Declare::Lexer { keyword => sub { $Some::Package::variable } }; which will cause the provided sub to be injected instead of the default sub.
SEE ALSO
Some examples can be found in the source download.
For more information about how Devel::Declare::Lexer works, read the documentation for Devel::Declare.
AUTHORS
Ian Kent - iankent@cpan.org - original author
http://www.iankent.co.uk/
COPYRIGHT AND LICENSE
This library is free software under the same terms as perl itself
Copyright (c) 2013 Ian Kent
Devel::Declare::Lexer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.