git-svn-id: svn://svn.code.sf.net/p/bitchx/code/tags/ircii-pana-1.1-final@1 13b04d17-f746-0410-82c6-800466cd88b0
339 lines
7.4 KiB
C++
339 lines
7.4 KiB
C++
#include "parse.h"
|
|
#include "list.h"
|
|
#include "grammar.h"
|
|
#include "lexicon.h"
|
|
|
|
extern Grammar grammar;
|
|
extern Lexicon lexicon;
|
|
Chart chart;
|
|
ActiveArcList arcs;
|
|
|
|
void parse(char *text) {
|
|
List *s = MakeList(text);
|
|
int i;
|
|
|
|
cout << *s << endl;
|
|
|
|
// go through each word and process
|
|
s->GoTop();
|
|
i = 1;
|
|
do {
|
|
if(lexicon.lookupWord(s->currItem()) == false) {
|
|
cout << "Can't find [" << s->currItem() << "] in the lexicon..." << endl;
|
|
return;
|
|
}
|
|
|
|
do {
|
|
chart.add(i, i + 1, lexicon.currNode());
|
|
} while(lexicon.lookupNext());
|
|
|
|
processAgenda();
|
|
|
|
i++;
|
|
} while(s->GoNext());
|
|
}
|
|
|
|
void processAgenda(void) {
|
|
int begLoc, endLoc;
|
|
genericNode *obj;
|
|
|
|
while(chart.process()) {
|
|
List *newMatch;
|
|
|
|
chart.getKey(begLoc, endLoc, obj);
|
|
|
|
cout << "find: " << *obj << endl;
|
|
newMatch = grammar.findMatch(obj);
|
|
|
|
if(newMatch) {
|
|
do {
|
|
cout << "Grammar search success:\n" << *newMatch << endl;
|
|
if(newMatch->length() <= 2) {
|
|
newMatch->GoTop();
|
|
chart.add(begLoc, endLoc, newMatch->currItemNode());
|
|
}
|
|
else {
|
|
activeArc *newArc;
|
|
|
|
newArc = new activeArc;
|
|
newArc->begLoc = begLoc;
|
|
newArc->endLoc = endLoc;
|
|
newArc->numFound = 1;
|
|
newArc->ruleLine = newMatch;
|
|
arcs.add(newArc);
|
|
}
|
|
} while((newMatch = grammar.findNext()));
|
|
}
|
|
else
|
|
cout << "Grammar search fail" << endl;
|
|
|
|
arcs.print();
|
|
|
|
// if there is nothing on the active arc list, we can skip checking arcs
|
|
if(!arcs.goTop())
|
|
continue;
|
|
|
|
do {
|
|
activeArc *checkArc;
|
|
|
|
checkArc = arcs.currArc();
|
|
if(checkArc->endLoc == begLoc) {
|
|
// find the current waiting component of this arc
|
|
checkArc->ruleLine->GoTop();
|
|
for(int i = 0; i <= checkArc->numFound; i++)
|
|
checkArc->ruleLine->GoNext();
|
|
|
|
cout << "Arc search: " << *checkArc->ruleLine->currItemNode() << ", "
|
|
<< *obj;
|
|
List *assign = unify(*checkArc->ruleLine->currItemNode(), *obj);
|
|
|
|
// did this arc unify with the current obj?
|
|
if(!assign) {
|
|
cout << " = FAIL" << endl;
|
|
}
|
|
else {
|
|
cout << " = " << *assign << endl;
|
|
// do the variable substitutions
|
|
assign = substitute(checkArc->ruleLine, assign);
|
|
|
|
if(assign->length() > (checkArc->numFound + 2)) {
|
|
// this arc has been extended, but not completed
|
|
cout << "Extended arc:\n" << *assign << "\n" << endl;
|
|
activeArc *newArc = new activeArc;
|
|
newArc->begLoc = checkArc->begLoc;
|
|
newArc->endLoc = endLoc;
|
|
newArc->numFound = checkArc->numFound + 1;
|
|
newArc->ruleLine = assign;
|
|
arcs.add(newArc);
|
|
}
|
|
else {
|
|
// this arc has been completed, we can add it to the chart
|
|
cout << "Completed arc:\n" << *assign << "\n" << endl;
|
|
assign->GoTop();
|
|
chart.add(checkArc->begLoc, endLoc, assign->currItemNode());
|
|
}
|
|
}
|
|
}
|
|
} while(arcs.goNext());
|
|
}
|
|
|
|
chart.print();
|
|
}
|
|
|
|
Chart::Chart() {
|
|
// mark this chart as being empty
|
|
rootPtr = currPtr = NULL;
|
|
}
|
|
|
|
void Chart::add(int begLoc, int endLoc, genericNode *obj) {
|
|
cout << '[' << begLoc << ',' << endLoc << ',' << *obj << ']' << endl;
|
|
|
|
if(rootPtr == NULL) {
|
|
rootPtr = new chartNode;
|
|
rootPtr->begLoc = begLoc;
|
|
rootPtr->endLoc = endLoc;
|
|
rootPtr->obj = obj;
|
|
rootPtr->processFlag = true;
|
|
rootPtr->nextPtr = NULL;
|
|
}
|
|
else {
|
|
chartNode *tmp = rootPtr;
|
|
|
|
while(tmp->nextPtr != NULL)
|
|
tmp = tmp->nextPtr;
|
|
|
|
tmp->nextPtr = new chartNode;
|
|
tmp = tmp->nextPtr;
|
|
tmp->begLoc = begLoc;
|
|
tmp->endLoc = endLoc;
|
|
tmp->obj = obj;
|
|
tmp->processFlag = true;
|
|
tmp->nextPtr = NULL;
|
|
}
|
|
}
|
|
|
|
bool Chart::process(void) {
|
|
chartNode *tmp = rootPtr;
|
|
|
|
while(tmp != NULL) {
|
|
if(tmp->processFlag)
|
|
return true;
|
|
|
|
tmp = tmp->nextPtr;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void Chart::getKey(int &begLoc, int &endLoc, genericNode *&obj) {
|
|
chartNode *tmp = rootPtr;
|
|
|
|
while(tmp != NULL) {
|
|
if(tmp->processFlag) {
|
|
// this key hasn't been processed yet, return it and mark as processed
|
|
begLoc = tmp->begLoc;
|
|
endLoc = tmp->endLoc;
|
|
obj = tmp->obj;
|
|
tmp->processFlag = false;
|
|
|
|
return;
|
|
}
|
|
|
|
tmp = tmp->nextPtr;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void Chart::print(void) {
|
|
cout << "Chart ";
|
|
for(int i = 0; i < 160 - 6; i++)
|
|
cout << '-';
|
|
cout << endl;
|
|
|
|
currPtr = rootPtr;
|
|
while(currPtr) {
|
|
cout << '[' << currPtr->begLoc << ',' << currPtr->endLoc << ','
|
|
<< currPtr->processFlag << ',' << *currPtr->obj << ']' << endl;
|
|
|
|
currPtr = currPtr->nextPtr;
|
|
}
|
|
cout << '\n' << endl;
|
|
}
|
|
|
|
bool Chart::findMatch(genericNode *obj, List *&assign, int begLoc, int &endLoc) {
|
|
searchObj = obj;
|
|
currPtr = rootPtr;
|
|
|
|
// empty chart has nothing to match -- abort
|
|
if(currPtr == NULL)
|
|
return false;
|
|
|
|
// go through each rule in the grammar and try to match it with the given obj
|
|
while(currPtr) {
|
|
if(currPtr->begLoc == begLoc) {
|
|
assign = unify(*currPtr->obj, *searchObj);
|
|
|
|
if(assign) {
|
|
endLoc = currPtr->endLoc;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
currPtr = currPtr->nextPtr;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
ActiveArcList::ActiveArcList() {
|
|
rootPtr = currPtr = NULL;
|
|
}
|
|
|
|
void ActiveArcList::add(activeArc *newArc) {
|
|
List *assign;
|
|
int endLoc;
|
|
|
|
if(rootPtr) {
|
|
arcNode *tmp = rootPtr;
|
|
|
|
// skip down to the last node
|
|
while(tmp->nextPtr)
|
|
tmp = tmp->nextPtr;
|
|
|
|
tmp->nextPtr = new arcNode;
|
|
tmp = tmp->nextPtr;
|
|
|
|
tmp->arc = newArc;
|
|
tmp->nextPtr = NULL;
|
|
}
|
|
else {
|
|
rootPtr = new arcNode;
|
|
rootPtr->arc = newArc;
|
|
rootPtr->nextPtr = NULL;
|
|
}
|
|
|
|
// whenever a new arc is added, we need to try to unify it with
|
|
// any of the completed objects on the chart to see if it can be extended
|
|
newArc->ruleLine->GoTop();
|
|
for(int i = 0; i <= newArc->numFound; i++)
|
|
newArc->ruleLine->GoNext();
|
|
|
|
if(!chart.findMatch(newArc->ruleLine->currItemNode(), assign, newArc->endLoc, endLoc))
|
|
return;
|
|
|
|
assign = substitute(newArc->ruleLine, assign);
|
|
if(assign->length() > (newArc->numFound + 2)) {
|
|
cout << "Extended arc: " << newArc->numFound + 1 << "\n" << *assign << "\n" << endl;
|
|
activeArc *newArc2 = new activeArc;
|
|
newArc2->begLoc = newArc->begLoc;
|
|
newArc2->endLoc = endLoc;
|
|
newArc2->numFound = newArc->numFound + 1;
|
|
arcs.add(newArc2);
|
|
}
|
|
else {
|
|
// this arc has been completed, we can add it to the chart
|
|
cout << "Completed arc:\n" << *assign << "\n" << endl;
|
|
|
|
chart.print();
|
|
|
|
assign->GoTop();
|
|
chart.add(newArc->begLoc, endLoc, assign->currItemNode());
|
|
}
|
|
}
|
|
|
|
bool ActiveArcList::goTop(void) {
|
|
if(rootPtr) {
|
|
currPtr = rootPtr;
|
|
return true;
|
|
}
|
|
else {
|
|
currPtr = NULL;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool ActiveArcList::goNext(void) {
|
|
if(currPtr && currPtr->nextPtr) {
|
|
currPtr = currPtr->nextPtr;
|
|
return true;
|
|
}
|
|
else {
|
|
currPtr = NULL;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
activeArc *ActiveArcList::currArc(void) {
|
|
if(currPtr)
|
|
return currPtr->arc;
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
void ActiveArcList::print(void) {
|
|
cout << "Active Arcs ";
|
|
for(int i = 0; i < 160-12; i++)
|
|
cout << '-';
|
|
cout << endl;
|
|
|
|
currPtr = rootPtr;
|
|
while(currPtr) {
|
|
cout << '[' << currPtr->arc->begLoc << ',' << currPtr->arc->endLoc << ',';
|
|
currPtr->arc->ruleLine->GoTop();
|
|
cout << *currPtr->arc->ruleLine->currItemNode();
|
|
for(int i = 0; i < currPtr->arc->numFound; i++) {
|
|
currPtr->arc->ruleLine->GoNext();
|
|
cout << ' ' << *currPtr->arc->ruleLine->currItemNode();
|
|
}
|
|
cout << " o";
|
|
while(currPtr->arc->ruleLine->GoNext())
|
|
cout << ' ' << *currPtr->arc->ruleLine->currItemNode();
|
|
cout << ']' << endl;
|
|
|
|
currPtr = currPtr->nextPtr;
|
|
}
|
|
|
|
cout << '\n' << endl;
|
|
}
|