Initial import of the ircii-pana-1.1-final source tree.
git-svn-id: svn://svn.code.sf.net/p/bitchx/code/tags/ircii-pana-1.1-final@1 13b04d17-f746-0410-82c6-800466cd88b0
This commit is contained in:
338
dll/europa/cse476/parse.cpp
Normal file
338
dll/europa/cse476/parse.cpp
Normal file
@@ -0,0 +1,338 @@
|
||||
#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;
|
||||
}
|
||||
Reference in New Issue
Block a user