1 #include "parse.h"
2 #include "list.h"
3 #include "grammar.h"
4 #include "lexicon.h"
5
6 extern Grammar grammar;
7 extern Lexicon lexicon;
8 Chart chart;
9 ActiveArcList arcs;
10
parse(char * text)11 void parse(char *text) {
12 List *s = MakeList(text);
13 int i;
14
15 cout << *s << endl;
16
17 // go through each word and process
18 s->GoTop();
19 i = 1;
20 do {
21 if(lexicon.lookupWord(s->currItem()) == false) {
22 cout << "Can't find [" << s->currItem() << "] in the lexicon..." << endl;
23 return;
24 }
25
26 do {
27 chart.add(i, i + 1, lexicon.currNode());
28 } while(lexicon.lookupNext());
29
30 processAgenda();
31
32 i++;
33 } while(s->GoNext());
34 }
35
processAgenda(void)36 void processAgenda(void) {
37 int begLoc, endLoc;
38 genericNode *obj;
39
40 while(chart.process()) {
41 List *newMatch;
42
43 chart.getKey(begLoc, endLoc, obj);
44
45 cout << "find: " << *obj << endl;
46 newMatch = grammar.findMatch(obj);
47
48 if(newMatch) {
49 do {
50 cout << "Grammar search success:\n" << *newMatch << endl;
51 if(newMatch->length() <= 2) {
52 newMatch->GoTop();
53 chart.add(begLoc, endLoc, newMatch->currItemNode());
54 }
55 else {
56 activeArc *newArc;
57
58 newArc = new activeArc;
59 newArc->begLoc = begLoc;
60 newArc->endLoc = endLoc;
61 newArc->numFound = 1;
62 newArc->ruleLine = newMatch;
63 arcs.add(newArc);
64 }
65 } while((newMatch = grammar.findNext()));
66 }
67 else
68 cout << "Grammar search fail" << endl;
69
70 arcs.print();
71
72 // if there is nothing on the active arc list, we can skip checking arcs
73 if(!arcs.goTop())
74 continue;
75
76 do {
77 activeArc *checkArc;
78
79 checkArc = arcs.currArc();
80 if(checkArc->endLoc == begLoc) {
81 // find the current waiting component of this arc
82 checkArc->ruleLine->GoTop();
83 for(int i = 0; i <= checkArc->numFound; i++)
84 checkArc->ruleLine->GoNext();
85
86 cout << "Arc search: " << *checkArc->ruleLine->currItemNode() << ", "
87 << *obj;
88 List *assign = unify(*checkArc->ruleLine->currItemNode(), *obj);
89
90 // did this arc unify with the current obj?
91 if(!assign) {
92 cout << " = FAIL" << endl;
93 }
94 else {
95 cout << " = " << *assign << endl;
96 // do the variable substitutions
97 assign = substitute(checkArc->ruleLine, assign);
98
99 if(assign->length() > (checkArc->numFound + 2)) {
100 // this arc has been extended, but not completed
101 cout << "Extended arc:\n" << *assign << "\n" << endl;
102 activeArc *newArc = new activeArc;
103 newArc->begLoc = checkArc->begLoc;
104 newArc->endLoc = endLoc;
105 newArc->numFound = checkArc->numFound + 1;
106 newArc->ruleLine = assign;
107 arcs.add(newArc);
108 }
109 else {
110 // this arc has been completed, we can add it to the chart
111 cout << "Completed arc:\n" << *assign << "\n" << endl;
112 assign->GoTop();
113 chart.add(checkArc->begLoc, endLoc, assign->currItemNode());
114 }
115 }
116 }
117 } while(arcs.goNext());
118 }
119
120 chart.print();
121 }
122
Chart()123 Chart::Chart() {
124 // mark this chart as being empty
125 rootPtr = currPtr = NULL;
126 }
127
add(int begLoc,int endLoc,genericNode * obj)128 void Chart::add(int begLoc, int endLoc, genericNode *obj) {
129 cout << '[' << begLoc << ',' << endLoc << ',' << *obj << ']' << endl;
130
131 if(rootPtr == NULL) {
132 rootPtr = new chartNode;
133 rootPtr->begLoc = begLoc;
134 rootPtr->endLoc = endLoc;
135 rootPtr->obj = obj;
136 rootPtr->processFlag = true;
137 rootPtr->nextPtr = NULL;
138 }
139 else {
140 chartNode *tmp = rootPtr;
141
142 while(tmp->nextPtr != NULL)
143 tmp = tmp->nextPtr;
144
145 tmp->nextPtr = new chartNode;
146 tmp = tmp->nextPtr;
147 tmp->begLoc = begLoc;
148 tmp->endLoc = endLoc;
149 tmp->obj = obj;
150 tmp->processFlag = true;
151 tmp->nextPtr = NULL;
152 }
153 }
154
process(void)155 bool Chart::process(void) {
156 chartNode *tmp = rootPtr;
157
158 while(tmp != NULL) {
159 if(tmp->processFlag)
160 return true;
161
162 tmp = tmp->nextPtr;
163 }
164
165 return false;
166 }
167
getKey(int & begLoc,int & endLoc,genericNode * & obj)168 void Chart::getKey(int &begLoc, int &endLoc, genericNode *&obj) {
169 chartNode *tmp = rootPtr;
170
171 while(tmp != NULL) {
172 if(tmp->processFlag) {
173 // this key hasn't been processed yet, return it and mark as processed
174 begLoc = tmp->begLoc;
175 endLoc = tmp->endLoc;
176 obj = tmp->obj;
177 tmp->processFlag = false;
178
179 return;
180 }
181
182 tmp = tmp->nextPtr;
183 }
184
185 return;
186 }
187
print(void)188 void Chart::print(void) {
189 cout << "Chart ";
190 for(int i = 0; i < 160 - 6; i++)
191 cout << '-';
192 cout << endl;
193
194 currPtr = rootPtr;
195 while(currPtr) {
196 cout << '[' << currPtr->begLoc << ',' << currPtr->endLoc << ','
197 << currPtr->processFlag << ',' << *currPtr->obj << ']' << endl;
198
199 currPtr = currPtr->nextPtr;
200 }
201 cout << '\n' << endl;
202 }
203
findMatch(genericNode * obj,List * & assign,int begLoc,int & endLoc)204 bool Chart::findMatch(genericNode *obj, List *&assign, int begLoc, int &endLoc) {
205 searchObj = obj;
206 currPtr = rootPtr;
207
208 // empty chart has nothing to match -- abort
209 if(currPtr == NULL)
210 return false;
211
212 // go through each rule in the grammar and try to match it with the given obj
213 while(currPtr) {
214 if(currPtr->begLoc == begLoc) {
215 assign = unify(*currPtr->obj, *searchObj);
216
217 if(assign) {
218 endLoc = currPtr->endLoc;
219 return true;
220 }
221 }
222
223 currPtr = currPtr->nextPtr;
224 }
225
226 return false;
227 }
228
ActiveArcList()229 ActiveArcList::ActiveArcList() {
230 rootPtr = currPtr = NULL;
231 }
232
add(activeArc * newArc)233 void ActiveArcList::add(activeArc *newArc) {
234 List *assign;
235 int endLoc;
236
237 if(rootPtr) {
238 arcNode *tmp = rootPtr;
239
240 // skip down to the last node
241 while(tmp->nextPtr)
242 tmp = tmp->nextPtr;
243
244 tmp->nextPtr = new arcNode;
245 tmp = tmp->nextPtr;
246
247 tmp->arc = newArc;
248 tmp->nextPtr = NULL;
249 }
250 else {
251 rootPtr = new arcNode;
252 rootPtr->arc = newArc;
253 rootPtr->nextPtr = NULL;
254 }
255
256 // whenever a new arc is added, we need to try to unify it with
257 // any of the completed objects on the chart to see if it can be extended
258 newArc->ruleLine->GoTop();
259 for(int i = 0; i <= newArc->numFound; i++)
260 newArc->ruleLine->GoNext();
261
262 if(!chart.findMatch(newArc->ruleLine->currItemNode(), assign, newArc->endLoc, endLoc))
263 return;
264
265 assign = substitute(newArc->ruleLine, assign);
266 if(assign->length() > (newArc->numFound + 2)) {
267 cout << "Extended arc: " << newArc->numFound + 1 << "\n" << *assign << "\n" << endl;
268 activeArc *newArc2 = new activeArc;
269 newArc2->begLoc = newArc->begLoc;
270 newArc2->endLoc = endLoc;
271 newArc2->numFound = newArc->numFound + 1;
272 arcs.add(newArc2);
273 }
274 else {
275 // this arc has been completed, we can add it to the chart
276 cout << "Completed arc:\n" << *assign << "\n" << endl;
277
278 chart.print();
279
280 assign->GoTop();
281 chart.add(newArc->begLoc, endLoc, assign->currItemNode());
282 }
283 }
284
goTop(void)285 bool ActiveArcList::goTop(void) {
286 if(rootPtr) {
287 currPtr = rootPtr;
288 return true;
289 }
290 else {
291 currPtr = NULL;
292 return false;
293 }
294 }
295
goNext(void)296 bool ActiveArcList::goNext(void) {
297 if(currPtr && currPtr->nextPtr) {
298 currPtr = currPtr->nextPtr;
299 return true;
300 }
301 else {
302 currPtr = NULL;
303 return false;
304 }
305 }
306
currArc(void)307 activeArc *ActiveArcList::currArc(void) {
308 if(currPtr)
309 return currPtr->arc;
310 else
311 return NULL;
312 }
313
print(void)314 void ActiveArcList::print(void) {
315 cout << "Active Arcs ";
316 for(int i = 0; i < 160-12; i++)
317 cout << '-';
318 cout << endl;
319
320 currPtr = rootPtr;
321 while(currPtr) {
322 cout << '[' << currPtr->arc->begLoc << ',' << currPtr->arc->endLoc << ',';
323 currPtr->arc->ruleLine->GoTop();
324 cout << *currPtr->arc->ruleLine->currItemNode();
325 for(int i = 0; i < currPtr->arc->numFound; i++) {
326 currPtr->arc->ruleLine->GoNext();
327 cout << ' ' << *currPtr->arc->ruleLine->currItemNode();
328 }
329 cout << " o";
330 while(currPtr->arc->ruleLine->GoNext())
331 cout << ' ' << *currPtr->arc->ruleLine->currItemNode();
332 cout << ']' << endl;
333
334 currPtr = currPtr->nextPtr;
335 }
336
337 cout << '\n' << endl;
338 }
339