AI-Prolog
view release on metacpan or search on metacpan
lib/AI/Prolog/Parser.pm view on Meta::CPAN
$self->skipspace;
$self->nextclause; # new set of vars
}
return $db;
}
sub resolve {
my ( $class, $db ) = @_;
foreach my $termlist ( values %{ $db->ht } ) {
$termlist->resolve($db);
}
}
sub _termlist {
my ($self) = @_;
my $termlist = TermList->new;
my @ts = $self->_term;
$self->skipspace;
if ( $self->current eq ':' ) {
$self->advance;
if ( $self->current eq '=' ) {
# we're parsing a primitive
$self->advance;
$self->skipspace;
my $id = $self->getnum;
$self->skipspace;
$termlist->{term} = $ts[0];
$termlist->{next} = Primitive->new($id);
}
elsif ( $self->current ne '-' ) {
$self->parseerror("Expected '-' after ':'");
}
else {
$self->advance;
$self->skipspace;
push @ts => $self->_term;
$self->skipspace;
while ( $self->current eq ',' ) {
$self->advance;
$self->skipspace;
push @ts => $self->_term;
$self->skipspace;
}
my @tsl;
for my $j ( reverse 1 .. $#ts ) {
$tsl[$j] = $termlist->new( $ts[$j], $tsl[ $j + 1 ] );
}
$termlist->{term} = $ts[0];
$termlist->{next} = $tsl[1];
}
}
else {
$termlist->{term} = $ts[0];
$termlist->{next} = undef;
}
if ( $self->current ne '.' ) {
$self->parseerror("Expected '.' Got '@{[$self->current]}'");
}
$self->advance;
return $termlist;
}
# This constructor is the simplest way to construct a term. The term is given
# in standard notation.
# Example: my $term = Term->new(Parser->new("p(1,a(X,b))"));
sub _term {
my ($self) = @_;
my $term = Term->new( undef, 0 );
my $ts = [];
my $i = 0;
$self->skipspace; # otherwise we crash when we hit leading
# spaces
if ( $self->current =~ /^[[:lower:]'"]$/ ) {
$term->{functor} = $self->getname;
$term->{bound} = 1;
$term->{deref} = 0;
if ( '(' eq $self->current ) {
$self->advance;
$self->skipspace;
$ts->[ $i++ ] = $self->_term;
$self->skipspace;
while ( ',' eq $self->current ) {
$self->advance;
$self->skipspace;
$ts->[ $i++ ] = $self->_term;
$self->skipspace;
}
if ( ')' ne $self->current ) {
$self->parseerror(
"Expecting: ')'. Got (@{[$self->current]})");
}
$self->advance;
$term->{args} = [];
$term->{args}[$_] = $ts->[$_] for 0 .. ( $i - 1 );
$term->{arity} = $i;
}
else {
$term->{arity} = 0;
}
}
elsif ( $self->current =~ /^[[:upper:]]$/ ) {
$term->{bound} = 1;
$term->{deref} = 1;
my ( $ref, $string ) = $self->getvar;
$term->{ref} = $ref;
$term->{varname} = $string;
}
elsif ( '_' eq $self->current && $self->peek =~ /^[\]\|\.;\s\,\)]$/ ) {
# temporary hack to allow anonymous variables
# this should really be cleaned up
$term->{bound} = 1;
$term->{deref} = 1;
my ( $ref, $string ) = $self->get_anon;
$term->{ref} = $ref;
$term->{varname} = $string;
}
elsif ( $self->current =~ /^[-.[:digit:]]$/ ) {
return Number->new( $self->getnum );
}
elsif ( '[' eq $self->current ) {
$self->advance;
( run in 0.723 second using v1.01-cache-2.11-cpan-d80b1682f3f )