Evaluating user-defined conditions

Andrew Beverley andy at andybev.com
Tue Jun 10 12:06:21 BST 2014


On Tue, 2014-06-10 at 12:23 +0200, Abigail wrote:
> 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.

Ah, okay, thanks.

> 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__

Brilliant, thanks for that, much appreciated. However, isn't that
similar to what I was trying to do, in that you're relying on the regex
to match (or otherwise) accordingly? And you'd still need to eval it
afterwards?

I'm going to need to allow strings to be matched. E.g:

[age] > 10 && [name] eq "jon"

which sounds dangerous for the very good reasons you outlined previously
(thanks for that - glad that I asked!)

Andy




More information about the london.pm mailing list