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