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