Files
bitchx/dll/europa/cse476/grammar.cpp
Kevin Easton 28febcfea9 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
2008-02-25 09:25:32 +00:00

144 lines
2.8 KiB
C++

// Copyright (c) 1998-99, Ed Schlunder
#include <fstream.h>
#include <iostream.h>
#include <string.h>
#include "grammar.h"
#include "gnode.h"
Grammar::Grammar(char *fileName) {
char buffer[1000];
ifstream inFile;
// specify that this is currently an empty grammar rule list
rootPtr = currPtr = NULL;
// try to open the grammar rules file
inFile.open(fileName);
if(!inFile) {
cout << "Grammar rules file can not be opened." << endl;
return;
}
while(inFile) {
inFile.getline(buffer, 999);
// ignore blank lines
if(strlen(buffer) < 2) continue;
trim(buffer);
insert(buffer);
}
}
void Grammar::insert(char *text) {
List *ruleLine = new List;
genericNode *obj;
char *tmp;
int length, level, beg, end;
length = strlen(text);
end = -1;
while(end < length) {
beg = end + 1;
// locate opening parenthesis
while(beg < length)
if(text[beg] == '(') break;
else beg++;
for(level = 0, end = beg + 1; end < length; end++) {
if((text[end] == ')') && (level == 0)) break;
// make sure that items encased within () are kept intact
if(text[end] == '(') level++;
if(text[end] == ')') level--;
}
end++;
tmp = new char[end - beg + 1];
strncpy(tmp, text + beg, end - beg);
tmp[end - beg] = 0;
if(strlen(tmp) == 0)
break;
// make a genericNode out of this phrasal object and add it to the ruleLine
// cout << '[' << tmp << ']' << endl;
obj = new genericNode(tmp);
ruleLine->InsertAfter(obj);
}
insert(ruleLine);
}
void Grammar::insert(List *ruleLine) {
grammarLine *tmp;
// cout << "grammarInsert: " << *ruleLine << endl;
if(rootPtr == NULL) {
rootPtr = new grammarLine;
rootPtr->line = ruleLine;
rootPtr->nextPtr = NULL;
}
else {
// find end of list
tmp = rootPtr;
while(tmp->nextPtr != NULL)
tmp = tmp->nextPtr;
// tack a new rule on the end of the list
tmp->nextPtr = new grammarLine;
tmp = tmp->nextPtr;
tmp->line = ruleLine;
tmp->nextPtr = NULL;
}
}
Grammar::~Grammar() {
}
List *Grammar::currLine(void) {
return currPtr->line;
}
void Grammar::goTop(void) {
currPtr = rootPtr;
}
bool Grammar::goNext(void) {
if(currPtr)
if(currPtr->nextPtr) {
currPtr = currPtr->nextPtr;
return true;
}
return false;
}
List *Grammar::findMatch(genericNode *obj) {
searchObj = obj;
currPtr = rootPtr;
return findNext();
}
List *Grammar::findNext(void) {
List *assign, *currLine;
// go through each rule in the grammar and try to match it with the given obj
while(currPtr) {
currLine = currPtr->line;
currLine->GoTop();
currLine->GoNext();
assign = unify(*currLine->currItemNode(), *searchObj);
currPtr = currPtr->nextPtr;
if(assign)
return substitute(currLine, assign);
}
return NULL;
}