From: Mike Taylor Date: Fri, 17 Dec 2004 15:29:00 +0000 (+0000) Subject: New X-Git-Url: http://sru.miketaylor.org.uk/cgi-bin?a=commitdiff_plain;h=fe37f9e6377eaa8977001ef017b339be7032760e;p=perl-pqf.git New --- diff --git a/lib/Net/Z3950/PQF/Node.pm b/lib/Net/Z3950/PQF/Node.pm new file mode 100644 index 0000000..50e9ef5 --- /dev/null +++ b/lib/Net/Z3950/PQF/Node.pm @@ -0,0 +1,257 @@ +# $Id: Node.pm,v 1.1 2004-12-17 15:29:00 mike Exp $ + +package Net::Z3950::PQF::Node; + +use strict; +use warnings; + + +=head1 NAME + +Net::Z3950::PQF::Node - Abstract class for nodes in a PQF parse tree + +=head1 SYNOPSIS + + $node = new Net::Z3950::PQF::Term('unix'); + $node->isa("Net::Z3950::PQF::Node") or die "oops"; + +=head1 DESCRIPTION + +This module implements the types for the nodes that make up a PQF +parse tree. Each such concrete type is a subclass of the abstract +base class +C, +and has a type whose name is of the form +CI. + +The following node types are defined: + +=over 4 + +=item C + +Represents an actual query term such as +C, +C<"brian"> +or +C<"Brian W. Kernighan">. + +The term is accompanied by zero or more +I, +each of which is a triple represented by a reference to a +three-element array. Each such array consists of an +I +which may be either an OID or a short descriptive string, +an integer +I, +and a +I +which may be either an integer or a string. + +=item C + +Represents an AND node with two sub-nodes. + +=item C + +Represents an OR node with two sub-nodes. + +=item C + +Represents a NOT node with two sub-nodes. In the Z39.50 Type-1 query, +and hence in PQF, NOT is a binary AND-NOT operator rather than than a +unary negation operator. + +=item C + +Represents a proximity node with two subnodes and five parameters: + +I: +a boolean indicating whether the condition indicated by the other +parameters should be inverted. + +I: +an integer indicating the number of units that may separate the +fragments identified by the subnodes. + +I: +a boolean indicating whether the elements indicated by the subnodes +are constrained to be in the same order as the subnodes themselves. + +I: +indicates the relation required on the specified distance in order +for the condition to be satisfied. + +I: +a short string indicating the units of proximity (C, +C, etc.) + +=back + +Except where noted, the methods described below are defined for all of +the concrete node types. + + +=head1 METHODS + +=head2 new() + + $term1 = new Net::Z3950::PQF::TermNode('brian', [ "bib-1", 1, 1003 ]); + $term2 = new Net::Z3950::PQF::TermNode('unix', [ "bib-1", 1, 4 ]); + $and = new Net::Z3950::PQF::AndNode($term1, $term2); + +Creates a new node object of the appropriate type. It is not possible +to instantiate the abstract node type, C, only its +concrete subclasses. + +The parameters required are different for different node types: + +=over 4 + +=item C + +The first parameter is the actual term, and the remainder are +attributes, each represented by a triple of +[ I, I, I ]. + +=item C, C, C + +The two parameters are nodes representing the subtrees. + +=item C + +The seven parameters are, in order: the two nodes representing the +subtrees, and the five parameters exclusion, distance, ordered, +relation and unit. + +=back + +=cut + +sub new { + my $class = shift(); + die "can't create an abstract $class"; +} + + +=head2 render() + + $node->render(0); + +Renders the contents of the tree rooted at the specified node, +indented to a level indicated by the parameter. This output is in a +human-readable form that is useful for debugging but probably not much +else. + +=cut + +sub render { + my $class = shift(); + die "can't render an abstract $class"; +} + + + +package Net::Z3950::PQF::TermNode; + +sub new { + my $class = shift(); + my($term, @attrs) = @_; + + return bless { + term => $term, + attrs => [ @attrs ], + }, $class; +} + +sub render { + my $this = shift(); + my($level) = @_; + + die "render() called with no level" if !defined $level; + my $text = ("\t" x $level) . "term: " . $this->{term} . "\n"; + foreach my $attr (@{ $this->{attrs} }) { + my($set, $type, $val) = @$attr; + $text .= ("\t" x ($level+1)) . "attr: $set $type=$val\n"; + } + + return $text; +} + + + +# PRIVATE class, used as base by AndNode, OrNode and NotNode +package Net::Z3950::PQF::BooleanNode; + +sub new { + my $class = shift(); + my(@sub) = @_; + + return bless { + sub => [ @sub ], + }, $class; +} + +sub render { + my $this = shift(); + my($level) = @_; + + die "render() called with no level" if !defined $level; + my $text = ("\t" x $level) . $this->_op() . "\n"; + foreach my $sub (@{ $this->{sub} }) { + $text .= $sub->render($level+1); + } + + return $text; +} + + + +package Net::Z3950::PQF::AndNode; +use vars qw(@ISA); +@ISA = qw(Net::Z3950::PQF::BooleanNode); + +sub _op { "and" } + + + +package Net::Z3950::PQF::OrNode; +use vars qw(@ISA); +@ISA = qw(Net::Z3950::PQF::BooleanNode); + +sub _op { "or" } + + + +package Net::Z3950::PQF::NotNode; +use vars qw(@ISA); +@ISA = qw(Net::Z3950::PQF::BooleanNode); + +sub _op { "not" } + + + +package Net::Z3950::PQF::ProxNode; + +sub new { + my $class = shift(); + die "### class $class not yet implemented"; +} + +sub render { + my $this = shift(); + die "you shouldn't have been able to make $this"; +} + + + + +=head1 PROVENANCE + +This module is part of the Net::Z3950::PQF distribution. The +copyright, authorship and licence are all as for the distribution. + +=cut + + +1;