# make_parser.pl use strict; use warnings; use Parse::RecDescent qw( ); my $grammar = <<'__EOI__'; { use strict; use warnings; sub dequote { my ($s) = @_; $s =~ s/^"//; $s =~ s/"\z//; $s =~ s/\\(.)/$1/sg; return $s; } } parse : list /\Z/ { $item[1] } list : term list_[ $item[1] ] list_ : "AND" and_list { [ $item[1] => $arg[0], @{$item[3]} ] } | "OR" or_list { [ $item[1] => $arg[0], @{$item[3]} ] } | { $arg[0] } and_list : term and_list_ { [ $item[1], @{$item[2]} ] } and_list_ : "AND" term and_list_ { [ $item[3], @{$item[4]} ] } | { [] } or_list : term or_list_ { [ $item[1], @{$item[2]} ] } or_list_ : "OR" term or_list_ { [ $item[3], @{$item[4]} ] } | { [] } term : IDENT | STRING | '(' list ')' { $item[2] } IDENT : /\w+/ STRING : /"(?:\\.|[^\\])*"/s { dequote($item[1]) } __EOI__ Parse::RecDescent->Precompile($grammar, 'Parser') or die("Bad grammar\n");