On Tue, Jun 10, 2014 at 12:06:21PM +0100, Andrew Beverley wrote: > 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?
Two key differences: - Your approach basically is "allow anything, except for the things matched", whily my approach is "only allow if matched". - You looked at the expression in a very localized way, while my patterns looks at the complete expression. > 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" Allow any string? Including strings that may potentially excute code? In that case, eval will be wrong. Or is the string just a list of alphanumerics? In which case, just add another clause to the definition of term. > > which sounds dangerous for the very good reasons you outlined previously > (thanks for that - glad that I asked!) Abigail