Evaluating user-defined conditions
Abigail
abigail at abigail.be
Tue Jun 10 11:23:24 BST 2014
On Tue, Jun 10, 2014 at 10:35:41AM +0100, Andrew Beverley wrote:
> On Tue, 2014-06-10 at 10:05 +0100, James Laver wrote:
> > I was sort of hoping that the not too subtle hints that using eval is a
> > bad idea would pay off. Apparently not.
>
> D'oh, I thought someone might say that... But it's so easy ;-)
>
> Got the message, will play with a parser.
Note that all you need is a *validating* parser. You don't have to bother
with building a parse tree, and evaluating the results -- *that* can be
left to Perl.
Here's a pattern that accepts expressions of the form you initially
posted (and I've replaced [var] with "var"):
#!/usr/bin/perl
use 5.010;
use strict;
use warnings;
no warnings 'syntax';
use Test::Regexp;
use Test::More;
my $pat = qr {
(?(DEFINE)
(?<expression> (?&term)
(?: \ * (?: [-<>+*] | && | eq ) \ * (?&expression))?)
(?<term> \( (?&expression) \) |
" [a-z]+ " |
[0-9]+))
^(?&expression)$
}x;
my $test = Test::Regexp:: -> new -> init (
keep_pattern => $pat,
no_keep_message => 1,
name => "Expression"
);
#
# Using (?<name>PAT) leaves traces in %- behind, even if they don't
# actually capture...
#
my $captures = [[expression => undef],
[term => undef]];
$test -> match ('"age" > 10 && "price" < ("age" + 5) * 10',
captures => $captures);
$test -> no_match ('"@{qx (rm -rf)}" && 1');
done_testing;
__END__
More information about the london.pm
mailing list