#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;
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(!arcs.goTop())
continue;
do {
activeArc *checkArc;
checkArc = arcs.currArc();
if(checkArc->endLoc == begLoc) {
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);
if(!assign) {
cout << " = FAIL" << endl;
}
else {
cout << " = " << *assign << endl;
assign = substitute(checkArc->ruleLine, assign);
if(assign->length() > (checkArc->numFound + 2)) {
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 {
cout << "Completed arc:\n" << *assign << "\n" << endl;
assign->GoTop();
chart.add(checkArc->begLoc, endLoc, assign->currItemNode());
}
}
}
} while(arcs.goNext());
}
chart.print();
}
Chart::Chart() {
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) {
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;
if(currPtr == NULL)
return false;
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;
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;
}
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 {
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;
}