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 )