IIB Parser
The Ignorance Is Bliss Parser
Result:
Command: With the long metal tongs remove the red marble from the tin object.
Parse: GetFromWith(marble1,box2,tongs);
This parser is experimental. It deals only with the objects and words listed below. Using words from the list, enter a command and click "Go" to parse that command. The parser will return which function it would call, and what parameters it would send to that function.
This parser is part of a larger project detailed at this link. The full source code of the parse is at the bottom of this page.
Objects: marble1: "small red marble" : item (can take, put, drop, etc.) marble2: "small steel/metal marble" : item (can take, put, drop, etc.) box1: "ornate wooden/wood box" : container (cannot take, put, drop..) box2: "small tin/metal box" : item, container (can take, put, drop, etc.) tongs: "metal tongs" : item, tool (can take, put, drop, use, etc.) Additional Words: take, get, remove, put, place, insert, drop, discard, examine, x, open, close, from, in, into, out of, with
The parser can resolve the objects as long as there is a minimum amount of information about each object. For example, the command: from out of the tin thing remove a steel object is correctly resolved as GetFrom(marble2,box2); just as drop red is correctly parsed as Drop(marble1); since the red marble is the only red object and the command is, therefore, not ambiguous.
The latest change includes disambiguation by type or class. If I say put box into box it sees that box1 is a container only, but box2 is both a container and an "item" (which is the word I picked for things that can go into a container). Therefore, it correctly guesses that I meant to put box2 into box1. Likewise if I say "put wood box into steel marble" it will tell me that "wood box" cannot be put into a container, and that "steel marble" is not a container. (For now the message is simply "--wrong type--".)
function parse1($cmd) {
// parse one-split commands: drop | object
global $split_words1;
$best_index = -1;
$p1 = -1;
foreach( $split_words1 as $index => $splits ) {
$split1 = strpos($cmd,$splits[0]);
if ($split1 !== FALSE){
$p1 = $split1;
$best_index = $index;
}
}
if ($best_index >= 0) {
$l1 = strlen($split_words1[$best_index][0]);
$pa = substr($cmd,$l1);
$fc = $split_words1[$best_index][1];
$pa = identify($pa,$split_words1[$best_index][2]);
return $fc."(".$pa.");";
}
return "";
}
function parse2($cmd) {
// parse two-split commands: take | object | from | object
global $split_words2;
$best_index = -1;
$p1 = -1;
$p2 = -1;
foreach( $split_words2 as $index => $splits ) {
$split1 = strpos($cmd,$splits[0]);
$split2 = strpos($cmd,$splits[1]);
if (($split1 !== FALSE)&&($split2 !== FALSE)){
if ($split1 < $split2 ) {
$p1 = $split1;
$p2 = $split2;
$best_index = $index;
}
}
}
if ($best_index >= 0) {
$l1 = strlen($split_words2[$best_index][0]);
$l2 = strlen($split_words2[$best_index][1]);
$pa = substr($cmd,$l1,$p2-$l1);
$pb = substr($cmd,$l2+$p2);
$fc = $split_words2[$best_index][2];
$pa = identify($pa,$split_words2[$best_index][3]);
$pb = identify($pb,$split_words2[$best_index][4],$pa);
$fc = str_replace('#a',$pa,$fc);
$fc = str_replace('#b',$pb,$fc);
return $fc;
}
return "";
}
function parse3($cmd) {
// parse three-split commands: take | object | from | object | with | object
global $split_words3;
$best_index = -1;
$p1 = -1;
$p2 = -1;
$p3 = -1;
foreach( $split_words3 as $index => $splits ) {
$split1 = strpos($cmd,$splits[0]);
$split2 = strpos($cmd,$splits[1]);
$split3 = strpos($cmd,$splits[2]);
if (($split1 !== FALSE)&&($split2 !== FALSE)&&($split3 !== FALSE)){
if ( ($split1 < $split2) && ($split2 < $split3 )) {
$p1 = $split1;
$p2 = $split2;
$p3 = $split3;
$best_index = $index;
}
}
}
if ($best_index >= 0) {
$l1 = strlen($split_words3[$best_index][0]);
$l2 = strlen($split_words3[$best_index][1]);
$l3 = strlen($split_words3[$best_index][2]);
$pa = substr($cmd,$l1,$p2-$l1);
$pb = substr($cmd,$l2+$p2,$p3-$p2-$l2);
$pc = substr($cmd,$l3+$p3);
$fc = $split_words3[$best_index][3];
$pa = identify($pa,$split_words3[$best_index][4]);
$pb = identify($pb,$split_words3[$best_index][5],$pa);
$pc = identify($pc,$split_words3[$best_index][6],$pa.' '.$pb);
$fc = str_replace('#a',$pa,$fc);
$fc = str_replace('#b',$pb,$fc);
$fc = str_replace('#c',$pc,$fc);
return $fc;
}
return "";
}
function identify($string,$type,$exclude=''){
// find the object named in the string and the type named and return it's ID tag
// exclude objects that have already been picked for a different role in this function call
global $obj_list;
$best_score = -99;
$best_index = -99;
$tie = 0;
$wrong_type = 0;
$words = explode(' ',$string);
foreach($obj_list as $index => $obj) {
$score = 0;
foreach($words as $word ) {
if (strpos($obj[1], $word) !== FALSE ) {
$score++;
}
}
$score = 100*$score / count($words); // percentage score
if (strpos($obj[2],$type) !== FALSE ) {
$score += 100; // bonus for being the right type
}
if (($score >= $best_score)&&$exclude&&(strpos($exclude,$obj_list[$index][0])!==FALSE)){
$score = 0;
}
if ($score > $best_score) {
$best_score = $score;
$best_index = $index;
$tie = 0;
} else if ( $score == $best_score ) {
$tie = 1;
}
}
if ( $best_score < 0 ) return "unknown";
if ( $best_score < 200 ) return "--wrong type--";
if ( $tie ) return "ambiguous";
return $obj_list[$best_index][0];
}
$split_words1 = array(
array('x ','Examine','object'),
array('examine ','Examine','object'),
array('drop ','Drop','item'),
array('get ','Get','item'),
array('discard ','Drop','item')
);
$split_words2 = array(
array('get ',' from ','GetFrom(#a,#b)','item','container'),
array('from ',' get ','GetFrom(#b,#a)','container','item'),
array('put ',' in ','PutInto(#a,#b)','item','container'),
array('in ',' put ','PutInto(#b,#a)','container','item'),
array('in ',' place ','PutInto(#b,#a)','container','item')
);
$split_words3 = array(
array('get ',' from ',' with ','GetFromWith(#a,#b,#c)','item','container','tool'),
array('from ',' get ',' with ','GetFromWith(#b,#a,#c)','container','item','tool'),
array('put ',' in ',' with ','PutIntoWith(#a,#b,#c)','item','container','tool'),
array('in ',' put ',' with ','PutIntoWith(#b,#a,#c)','container','item','tool'),
array('with ',' put ',' in ','PutIntoWith(#b,#c,#a)','tool','item','container'),
array('with ',' get ',' from ','GetFromWith(#b,#c,#a)','tool','item','container')
);
$obj_list = array(
array('marble1','small red marble item thing object','object item'),
array('marble2','small steel metal marble item thing object','object item'),
array('box1','ornate wooden wood box item thing object container','object container'),
array('box2','small tin metal box item thing object container','object item container'),
array('tongs','long metal tongs item thing object','object item tool')
);
function normalize($cmd) {
// remove articles, trim leading/trailing spaces and reduce multiple spaces to one space.
// also replace compound words with aliases
$cmd = ' '.$cmd;
$cmd=strtolower($cmd);
$cmd=str_replace(' the ',' ',$cmd);
$cmd=str_replace(' a ',' ',$cmd);
$cmd=str_replace(' an ',' ',$cmd);
$cmd=str_replace(' out of ',' from ',$cmd);
$cmd=str_replace(' take ',' get ',$cmd);
$cmd=str_replace(' remove ',' get ',$cmd);
$cmd=str_replace(' into ',' in ',$cmd);
$cmd=str_replace(' insert ',' put ',$cmd);
$cmd=str_replace(' place ',' put ',$cmd);
$cmd=str_replace(' using ',' with ',$cmd);
$cmd=str_replace(',',' ',$cmd);
$cmd=str_replace('.',' ',$cmd);
$cmd=str_replace('!',' ',$cmd);
$cmd=str_replace(';',' ',$cmd);
$cmd=str_replace(':',' ',$cmd);
$cmd=str_replace(' ',' ',$cmd);
$cmd=str_replace(' ',' ',$cmd);
return trim($cmd);
}
Experimental parser. Created: Jan. 22, 2012 -
Last Revision: Jan. 22, 2012