#include <string.h>
#include "gnode.h"
#include "list.h"
void trim(char *text) {
int i, j, len;
len = strlen(text);
if(len == 0) return;
for(i = 0; i < len; i++)
if(text[i] != ' ') break;
if(i > 0)
for(j = 0; text[i] != 0; j++, i++)
text[j] = text[i];
for(j = strlen(text); j > 1; j--)
if(text[j-1] != ' ') {
text[j] = 0;
break;
}
}
genericNode::genericNode(char *word, List *features) {
if(word) {
name = new char[strlen(word)];
strcpy(name, word);
}
else
word = NULL;
featureList = features;
}
genericNode::genericNode(char *obj) {
unsigned int i, j;
for(i = 0; i < strlen(obj); i++)
if(obj[i] != ' ') break;
if(obj[i] == '(') {
name = NULL;
j = i;
}
else {
for(j = i; j < strlen(obj); j++)
if(obj[j] == ' ') break;
name = new char[j - i + 1];
strncpy(name, obj, j - i);
name[j - i] = 0;
j++;
}
char *tmp = obj + j;
featureList = makeFeatureList(tmp);
}
ostream& operator<<(ostream &out_file, genericNode const &n) {
if(n.name == NULL)
out_file << "(nil";
else
out_file << '(' << n.name;
if(n.featureList)
out_file << ' ' << *n.featureList;
out_file << ')';
return out_file;
}
List *unify(genericNode &s, genericNode &g) {
List &sFeatures = *s.featureList, &gFeatures = *g.featureList, *currFeature;
List *assignList = new List;
char *featureName;
List *featureValueA, *featureValueB;
if(!sFeatures.GoTop()) return new List;
if(!gFeatures.GoTop()) return new List;
do {
currFeature = sFeatures.currItemList();
currFeature->GoTop();
featureName = currFeature->currItem();
currFeature->GoNext();
featureValueA = currFeature->currItemList();
featureValueB = g.lookupFeature(featureName);
if(featureValueB != NULL) {
List *assignment = cmpFeatures(*featureValueA, *featureValueB);
if(assignment == NULL) {
delete assignList;
return NULL;
}
if(!assignment->empty())
assignList->InsertAfter(assignment);
}
} while(sFeatures.GoNext());
return assignList;
}
List *cmpFeatures(List &a, List &b) {
char *valueA, *valueB;
a.GoTop();
do {
valueA = a.currItem();
b.GoTop();
do {
valueB = b.currItem();
if(strcmp(valueA, valueB) == 0)
return new List;
if(valueA[0] == '?') {
List *assignList = new List;
assignList->InsertAfter(valueA);
assignList->InsertAfter(&b);
return assignList;
}
if(valueB[0] == '?') {
List *assignList = new List;
assignList->InsertAfter(valueB);
assignList->InsertAfter(&a);
return assignList;
}
} while(b.GoNext());
} while(a.GoNext());
return NULL;
}
List *genericNode::lookupFeature(const char *name) const {
char *tmp;
List *featureSeek;
if(featureList == NULL) return NULL;
featureList->GoTop();
do {
featureSeek = featureList->currItemList();
featureSeek->GoTop();
tmp = featureSeek->currItem();
if(strcmp(tmp, name) == 0) {
featureSeek->GoNext();
return featureSeek->currItemList();
}
} while(featureList->GoNext());
return NULL;
}
char *genericNode::word(void) {
return name;
}
genericNode::~genericNode() {
delete name;
delete featureList;
}
List *genericNode::features(void) {
return featureList;
}
genericNode *substitute(genericNode *old, List *assign) {
genericNode *subst;
subst = new genericNode(old->name, substitute(old->featureList, assign));
return subst;
}