79 lines
1.6 KiB
Perl
Executable File
79 lines
1.6 KiB
Perl
Executable File
#!/usr/bin/perl
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
use XML::Simple;
|
|
use Data::Dumper;
|
|
|
|
die("Usage: $0 aiml.xml\n") unless($ARGV[0]);
|
|
open(XML,"<$ARGV[0]") or die("open($ARGV[0]): $!\n");
|
|
my $aiml = '';
|
|
while(<XML>) {
|
|
$aiml .= $_;
|
|
}
|
|
close(XML);
|
|
|
|
my $parser = XML::Simple->new();
|
|
my $xml = $parser->XMLin($aiml);
|
|
|
|
print "xml: " . Dumper($xml) . "\n";
|
|
|
|
|
|
our $knowledge = {};
|
|
foreach my $c (@{$xml->{category}}) {
|
|
print "pattern: $c->{pattern}\n";
|
|
&addKnowledge($knowledge,$c->{pattern},$c->{template});
|
|
}
|
|
|
|
print "Knowledge: " . Dumper($knowledge) . "\n";
|
|
|
|
print "> ";
|
|
while(my $input = <STDIN>) {
|
|
chomp($input);
|
|
print &findAnswer($knowledge,$input) . "\n";
|
|
print "> ";
|
|
}
|
|
|
|
sub findAnswer {
|
|
my ($struct,$input) = @_;
|
|
my ($key,$rest) = split(/\s+/,$input,2);
|
|
$key = '*' unless($struct->{uc($key)});
|
|
if($rest) {
|
|
if($struct->{uc($key)}) {
|
|
&findAnswer($struct->{uc($key)},$rest);
|
|
} elsif($struct->{template}) {
|
|
return(&parseAnswer($struct));
|
|
} elsif($struct->{'*'}) {
|
|
&findAnswer($struct->{'*'},$rest);
|
|
}
|
|
} else {
|
|
return(&parseAnswer($struct->{uc($key)}));
|
|
}
|
|
}
|
|
|
|
sub parseAnswer {
|
|
my ($struct) = @_;
|
|
if(ref($struct->{template}) eq '') {
|
|
return($struct->{template});
|
|
} elsif(ref($struct->{template}) eq 'HASH') {
|
|
if($struct->{template}->{random}) {
|
|
my @r = @{$struct->{template}->{random}->{li}};
|
|
srand($$^time^$struct);
|
|
return($r[rand(int($#r) + 1)]);
|
|
}
|
|
}
|
|
return('I do not know what that means.');
|
|
}
|
|
|
|
sub addKnowledge {
|
|
my ($ref,$pattern,$template) = @_;
|
|
my ($key,$rest) = split(/\s+/,$pattern,2);
|
|
if($rest) {
|
|
&addKnowledge($ref->{uc($key)},$rest,$template);
|
|
} else {
|
|
$ref->{uc($key)}->{template} = $template;
|
|
}
|
|
return(1);
|
|
}
|