# search.yp # # Copyright (C) 2013 Tim Retout # # Copying and distribution of this file, with or without modification, # are permitted in any medium without royalty. This file is offered as-is, # without any warranty. %left OR %left AND %left NOT %% search: LPAREN search RPAREN { "( $_[2] )" } | search OR search { "( $_[1] OR $_[3] )" } | search AND search { "( $_[1] AND $_[3] )" } | search search %prec AND { "( $_[1] AND $_[2] )" } | NOT search { "(!$_[2])" } | TERM { "$_[1]" } ; %% sub _error { exists $_[0]->YYData->{ERRMSG} and do { print $_[0]->YYData->{ERRMSG}; delete $_[0]->YYData->{ERRMSG}; return; }; print "Syntax error.\n"; } sub _lexer { my $parser = shift; $parser->YYData->{INPUT} =~ s/^\s*//; for ($parser->YYData->{INPUT}) { s/^(or)\b//i and return ('OR', $1); s/^(and)\b//i and return ('AND', $1); s/^(not|-)\b//i and return ('NOT', $1); s/^\(// and return ('LPAREN', '('); s/^\)// and return ('RPAREN', ')'); s/^("[^"]*")// and return ('TERM', $1); s/^([^()\s]+)// and return ('TERM', $1); } return ('', undef); } sub run { my $class = shift; while (<>) { chomp; my $self = $class->new; $self->YYData->{INPUT} = $_; my $result = $self->YYParse( yylex => \&_lexer, yyerror => \&_error); print $result . "\n"; } }