Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
BitchX
GitHub Repository: BitchX/BitchX1.3
Path: blob/master/dll/europa/cse476/list.cpp
1074 views
1
// Copyright (c) 1998-99, Ed Schlunder
2
3
#include <string.h>
4
#include "list.h"
5
6
// ---------------------------------------------------------------------------
7
// Class Implementation: List
8
// ---------------------------------------------------------------------------
9
List::List() {
10
rootPtr = NULL;
11
currPtr = NULL;
12
}
13
14
List::~List() {
15
listNode *tmpPtr = rootPtr, *nextPtr;
16
17
// go through the list and delete each node
18
while(tmpPtr) {
19
nextPtr = tmpPtr->nextPtr;
20
if(tmpPtr->item)
21
delete tmpPtr->item;
22
if(tmpPtr->itemList)
23
delete tmpPtr->itemList;
24
if(tmpPtr->itemNode)
25
delete tmpPtr->itemNode;
26
27
delete tmpPtr;
28
tmpPtr = nextPtr;
29
}
30
};
31
32
void List::InsertBefore(char *item) {
33
// this version does char strings
34
35
if(rootPtr == NULL) {
36
// creating the first node in a previously empty list.
37
rootPtr = new listNode;
38
39
rootPtr->item = new char[strlen(item) + 1];
40
strcpy(rootPtr->item, item);
41
rootPtr->itemList = NULL;
42
rootPtr->itemNode = NULL;
43
44
rootPtr->nextPtr = NULL;
45
rootPtr->prevPtr = NULL;
46
47
currPtr = rootPtr;
48
}
49
else {
50
// create a new node and insert it before currPtr's node
51
listNode *newPtr = new listNode;
52
53
newPtr->nextPtr = currPtr;
54
newPtr->prevPtr = currPtr->prevPtr;
55
newPtr->item = new char[strlen(item) + 1];
56
strcpy(newPtr->item, item);
57
newPtr->itemList = NULL;
58
newPtr->itemNode = NULL;
59
60
currPtr->prevPtr = newPtr;
61
if(newPtr->prevPtr)
62
newPtr->prevPtr->nextPtr = newPtr;
63
64
currPtr = newPtr;
65
}
66
}
67
68
void List::InsertBefore(List *item) {
69
// this version does Lists
70
71
if(rootPtr == NULL) {
72
rootPtr = new listNode;
73
74
rootPtr->item = NULL;
75
rootPtr->itemList = item;
76
rootPtr->itemNode = NULL;
77
78
rootPtr->nextPtr = NULL;
79
rootPtr->prevPtr = NULL;
80
81
currPtr = rootPtr;
82
}
83
else {
84
listNode *newPtr = new listNode;
85
86
newPtr->item = NULL;
87
newPtr->itemList = item;
88
newPtr->itemNode = NULL;
89
newPtr->nextPtr = currPtr;
90
newPtr->prevPtr = currPtr->prevPtr;
91
92
currPtr->prevPtr = newPtr;
93
if(newPtr->prevPtr)
94
newPtr->prevPtr->nextPtr = newPtr;
95
96
currPtr = newPtr;
97
}
98
}
99
100
void List::InsertBefore(genericNode *item) {
101
if(rootPtr == NULL) {
102
rootPtr = new listNode;
103
104
rootPtr->item = NULL;
105
rootPtr->itemList = NULL;
106
rootPtr->itemNode = item;
107
108
rootPtr->nextPtr = NULL;
109
rootPtr->prevPtr = NULL;
110
111
currPtr = rootPtr;
112
}
113
else {
114
listNode *newPtr = new listNode;
115
116
newPtr->item = NULL;
117
newPtr->itemList = NULL;
118
newPtr->itemNode = item;
119
newPtr->nextPtr = currPtr;
120
newPtr->prevPtr = currPtr->prevPtr;
121
122
currPtr->prevPtr = newPtr;
123
if(newPtr->prevPtr)
124
newPtr->prevPtr->nextPtr = newPtr;
125
126
currPtr = newPtr;
127
}
128
}
129
130
void List::InsertAfter(char *item) {
131
if(rootPtr == NULL) {
132
rootPtr = new listNode;
133
rootPtr->prevPtr = NULL;
134
rootPtr->nextPtr = NULL;
135
rootPtr->itemList = NULL;
136
rootPtr->itemNode = NULL;
137
rootPtr->item = new char[strlen(item) + 1];
138
strcpy(rootPtr->item, item);
139
140
currPtr = rootPtr;
141
}
142
else {
143
listNode *newPtr = new listNode;
144
145
newPtr->nextPtr = currPtr->nextPtr;
146
newPtr->prevPtr = currPtr;
147
newPtr->itemList = NULL;
148
newPtr->itemNode = NULL;
149
newPtr->item = new char[strlen(item) + 1];
150
strcpy(newPtr->item, item);
151
152
if(newPtr->nextPtr)
153
newPtr->nextPtr->prevPtr = newPtr;
154
newPtr->prevPtr->nextPtr = newPtr;
155
156
currPtr = newPtr;
157
}
158
}
159
160
void List::InsertAfter(List *item) {
161
if(rootPtr == NULL) {
162
rootPtr = new listNode;
163
rootPtr->prevPtr = NULL;
164
rootPtr->nextPtr = NULL;
165
rootPtr->item = NULL;
166
rootPtr->itemList = item;
167
rootPtr->itemNode = NULL;
168
169
currPtr = rootPtr;
170
}
171
else {
172
listNode *newPtr = new listNode;
173
174
newPtr->nextPtr = currPtr->nextPtr;
175
newPtr->prevPtr = currPtr;
176
newPtr->item = NULL;
177
newPtr->itemList = item;
178
newPtr->itemNode = NULL;
179
180
if(newPtr->nextPtr)
181
newPtr->nextPtr->prevPtr = newPtr;
182
newPtr->prevPtr->nextPtr = newPtr;
183
184
currPtr = newPtr;
185
}
186
}
187
188
void List::InsertAfter(genericNode *item) {
189
if(rootPtr == NULL) {
190
rootPtr = new listNode;
191
rootPtr->prevPtr = NULL;
192
rootPtr->nextPtr = NULL;
193
rootPtr->item = NULL;
194
rootPtr->itemList = NULL;
195
rootPtr->itemNode = item;
196
197
currPtr = rootPtr;
198
}
199
else {
200
listNode *newPtr = new listNode;
201
202
newPtr->nextPtr = currPtr->nextPtr;
203
newPtr->prevPtr = currPtr;
204
newPtr->item = NULL;
205
newPtr->itemList = NULL;
206
newPtr->itemNode = item;
207
208
if(newPtr->nextPtr)
209
newPtr->nextPtr->prevPtr = newPtr;
210
newPtr->prevPtr->nextPtr = newPtr;
211
212
currPtr = newPtr;
213
}
214
}
215
216
bool List::GoTop(void) {
217
currPtr = rootPtr;
218
219
if(currPtr == NULL)
220
return false;
221
else
222
return true;
223
}
224
225
bool List::GoNext(void) {
226
if(!currPtr)
227
return false;
228
229
currPtr = currPtr->nextPtr;
230
if(currPtr == NULL)
231
return false;
232
else
233
return true;
234
}
235
236
bool List::GoPrev(void) {
237
if(!currPtr)
238
return false;
239
240
currPtr = currPtr->prevPtr;
241
return true;
242
}
243
244
bool List::GoItem(int n) {
245
if(!rootPtr) // if empty list, abort
246
return false;
247
248
currPtr = rootPtr;
249
250
while(n--) { // visit each node from the root up to n nodes deep
251
if(!currPtr->nextPtr)
252
break;
253
254
currPtr = currPtr->nextPtr;
255
}
256
257
if(currPtr == NULL)
258
return false;
259
else
260
return true;
261
}
262
263
char *List::currItem(void) {
264
if(currPtr)
265
return currPtr->item;
266
else
267
return NULL;
268
}
269
270
List *List::currItemList(void) {
271
if(currPtr)
272
return currPtr->itemList;
273
else
274
return NULL;
275
}
276
277
genericNode *List::currItemNode(void) {
278
if(currPtr)
279
return currPtr->itemNode;
280
else
281
return NULL;
282
}
283
284
void List::Print(void) {
285
listNode *tmpPtr = rootPtr;
286
287
cout << "(";
288
while(tmpPtr) {
289
if(tmpPtr->item)
290
cout << tmpPtr->item << " ";
291
292
if(tmpPtr->itemList)
293
tmpPtr->itemList->Print();
294
295
if(tmpPtr->itemNode)
296
cout << tmpPtr->itemNode;
297
298
tmpPtr = tmpPtr->nextPtr;
299
}
300
cout << "\b) ";
301
}
302
303
304
List *MakeList(char *text) {
305
int length, i, j;
306
char *tmp = text;
307
List *l = new List;
308
309
length = strlen(text);
310
for(i = 0; i < length; i++) {
311
if(text[i] == '{' || text[i] == '(') {
312
// sub-list found
313
for(j = i + 1; j < length; j++)
314
if(text[j] == '}' || text[j] == ')')
315
break;
316
317
tmp = new char[j - i];
318
strncpy(tmp, text + i + 1, j - i - 1);
319
tmp[j - i - 1] = 0;
320
321
l->InsertAfter(MakeList(tmp));
322
delete tmp;
323
i = j + 1;
324
}
325
else if(text[i] != ' ' && text[i] != '\t' && text[i] != '.') {
326
// item found
327
for(j = i + 1; j < length; j++)
328
if(text[j] == ' ' || text[j] == '\t' || text[j] == '.')
329
break;
330
tmp = new char[j - i + 1];
331
strncpy(tmp, text + i, j - i);
332
tmp[j-i] = 0;
333
334
l->InsertAfter(tmp);
335
if(text[j] == '.')
336
l->InsertAfter(".");
337
delete tmp;
338
i = j;
339
}
340
}
341
342
return l;
343
}
344
345
List *MakeFeatList(char *text) {
346
int length, i, j;
347
char *tmp;
348
List *l = new List;
349
350
length = strlen(text);
351
for(i = 0; i < length; i++) {
352
for(j = i; j < length; j++)
353
if(text[j] == ' ')
354
break;
355
356
for(j++; j < length; j++)
357
if(text[j] == ' ' || text[j] == '}')
358
break;
359
360
if(text[j+1] == '{')
361
for(j++; j < length; j++)
362
if(text[j] == '}') {
363
j++;
364
break;
365
}
366
367
tmp = new char[j - i + 1];
368
strncpy(tmp, text + i, j - i);
369
tmp[j - i] = 0;
370
// cout << "Mklist: [" << tmp << "]" << endl;
371
l->InsertAfter(MakeList(tmp));
372
delete tmp;
373
374
i = j;
375
}
376
377
return l;
378
}
379
// ---------------------------------------------------------------------------
380
381
// Creates a list of features from a string. Example string:
382
// ((CAT NP) (AGR ?a))
383
List *makeFeatureList(char *text) {
384
int length, i, j, level, beg, end;
385
char *tmp, *thisList;
386
List *l = new List;
387
388
length = strlen(text);
389
390
// locate opening parenthesis
391
for(i = 0; i < length; i++)
392
if(text[i] == '(') break;
393
394
// no list given if no opening parenthesis found -- abort
395
if(i == length) return NULL;
396
397
// get -past- the (
398
i++;
399
400
// find end of this list
401
for(level = 1, j = i+1; j < length; j++) {
402
if(text[j] == ')') level--;
403
if(text[j] == '(') level++;
404
}
405
406
j--;
407
408
// make a new string containing a copy of the list text we want to work
409
// with only...
410
thisList = new char[j - i + 1];
411
strncpy(thisList, text + i, j - i);
412
thisList[j - i] = 0;
413
trim(thisList);
414
415
// cout << "thisList: [" << thisList << "]" << endl;
416
417
// step through the list text and take out each item (*tmp)
418
length = strlen(thisList);
419
end = -1;
420
while(end < length) {
421
beg = end + 1;
422
423
// find the end of this item
424
for(level = 0, end = beg; end < length; end++) {
425
if((thisList[end] == ' ') && (level == 0))
426
break;
427
428
// make sure that items encased within ( ) are kept as one piece
429
if(thisList[end] == '(') level++;
430
if(thisList[end] == ')') level--;
431
}
432
433
// make a copy of the text just for this item
434
tmp = new char[end - beg + 1];
435
strncpy(tmp, thisList + beg, end - beg);
436
tmp[end - beg] = 0;
437
438
// is this item a sub list?
439
if(tmp[0] == '(')
440
l->InsertAfter(makeFeatureList(tmp));
441
else
442
l->InsertAfter(tmp);
443
444
delete tmp;
445
}
446
447
// free up memory for temporary list string
448
delete thisList;
449
return l;
450
}
451
452
ostream &operator<<(ostream &out_file, const List &l) {
453
if(&l == NULL) {
454
out_file << "nil";
455
return out_file;
456
}
457
458
listNode *tmpPtr = l.rootPtr;
459
460
// is this an empty list?
461
if(tmpPtr == NULL)
462
out_file << "()";
463
else {
464
out_file << "(";
465
466
// print out first item without a separating space for it
467
if(tmpPtr->item) out_file << tmpPtr->item;
468
if(tmpPtr->itemList) out_file << *tmpPtr->itemList;
469
if(tmpPtr->itemNode) out_file << *tmpPtr->itemNode;
470
471
// step through the linked list of List items and print each one...
472
while((tmpPtr = tmpPtr->nextPtr)) {
473
if(tmpPtr->item) out_file << ' ' << tmpPtr->item;
474
if(tmpPtr->itemList) out_file << ' ' << *tmpPtr->itemList;
475
if(tmpPtr->itemNode) out_file << ' ' << *tmpPtr->itemNode;
476
}
477
out_file << ')';
478
}
479
480
return out_file;
481
}
482
483
bool List::empty(void) {
484
if(rootPtr == NULL)
485
return true;
486
else
487
return false;
488
}
489
490
int List::length(void) {
491
listNode *tmp;
492
int num;
493
494
// count each node in the list and return the count
495
tmp = rootPtr;
496
num = 0;
497
while(tmp) {
498
num++;
499
tmp = tmp->nextPtr;
500
}
501
502
return num;
503
}
504
505
List *findSubst(char *var, List *assign) {
506
if(assign->GoTop() == false)
507
return NULL;
508
509
do {
510
List *varSubst = assign->currItemList();
511
varSubst->GoTop();
512
513
// is this the variable that we are trying to find?
514
if(strcmp(varSubst->currItem(), var) == 0) {
515
varSubst->GoNext();
516
return varSubst->currItemList();
517
}
518
} while(assign->GoNext());
519
520
// couldn't find var in the variable substitution list
521
return NULL;
522
}
523
524
List *substitute(List *old, List *assign) {
525
List *subst = new List;
526
listNode *tmp;
527
528
tmp = old->rootPtr;
529
while(tmp) {
530
if(tmp->item) {
531
// cout << "recreating item: " << tmp->item << endl;
532
if(tmp->item[0] == '?') {
533
// variable may need to be substituted
534
List *newItem = findSubst(tmp->item, assign);
535
if(newItem == NULL)
536
subst->InsertAfter(tmp->item);
537
else {
538
newItem->GoTop();
539
do {
540
if(newItem->currItem())
541
subst->InsertAfter(newItem->currItem());
542
if(newItem->currItemList())
543
subst->InsertAfter(newItem->currItemList());
544
if(newItem->currItemNode())
545
subst->InsertAfter(newItem->currItemNode());
546
} while(newItem->GoNext());
547
}
548
}
549
else
550
// constants just stay
551
subst->InsertAfter(tmp->item);
552
}
553
554
// just call ourselves recursively for sublists
555
if(tmp->itemList) {
556
// cout << "recreating list: " << *tmp->itemList << endl;
557
subst->InsertAfter(substitute(tmp->itemList, assign));
558
}
559
560
if(tmp->itemNode) {
561
// cout << "recreating genericNode: " << *tmp->itemNode << endl;
562
subst->InsertAfter(new genericNode(NULL, substitute(tmp->itemNode->features(), assign)));
563
}
564
565
tmp = tmp->nextPtr;
566
}
567
568
return subst;
569
}
570
571