|
|
1.1 root 1: /* $Header: llparse.c,v 2.2 88/09/19 12:54:59 nhall Exp $ */
2: /* $Source: /var/home/tadl/src/argo/xebec/RCS/llparse.c,v $ */
3: /*
4: * ************************* NOTICE *******************************
5: * This code is in the public domain. It cannot be copyrighted.
6: * This ll parser was originally written by Keith Thompson for the
7: * University of Wisconsin Crystal project.
8: * It was based on an FMQ lr parser written by Jon Mauney at the
9: * University of Wisconsin.
10: * It was subsequently modified very slightly by Nancy Hall at the
11: * University of Wisconsin for the Crystal project.
12: * ****************************************************************
13: */
14: #include "xebec.h"
15: #include "llparse.h"
16: #include "main.h"
17: #include <stdio.h>
18:
19: #include "debug.h"
20:
21: #define LLMINACTION -LLINF
22:
23: short llparsestack[STACKSIZE];
24: short llstackptr = 0;
25: LLtoken lltoken;
26:
27: llparse()
28: {
29: register havetoken = FALSE;
30: register sym;
31: register LLtoken *t = &lltoken;
32: register parseaction;
33: register accepted = FALSE;
34:
35: llpushprod(llnprods-1); /* $$$ ::= <start symbol> */
36:
37: do {
38: sym = llparsestack[llstackptr];
39: IFDEBUG(L)
40: printf("llparse() top of loop, llstackptr=%d, sym=%d\n",
41: llstackptr, sym);
42: ENDDEBUG
43:
44: if(sym < 0) {
45: /* action symbol */
46: if(sym <= LLMINACTION) {
47: for(;sym<=LLMINACTION;sym++) {
48: llaction(1, t); /* calls llfinprod */
49: }
50: llstackptr--;
51: continue;
52: } else { llaction(-sym, t);
53: llstackptr--;
54: continue;
55: }
56: }
57:
58: if(sym < llnterms) {
59:
60: /* it's a terminal symbol */
61:
62: if(!havetoken) {
63: llgettoken(t);
64: havetoken = TRUE;
65: }
66:
67: if(sym == t->llterm) {
68: llpushattr(t->llattrib);
69: llaccept(t);
70: llstackptr--; /* pop terminal */
71: if(t->llterm == llnterms-1) { /* end symbol $$$ */
72: accepted = TRUE;
73: } else {
74: havetoken = FALSE;
75: }
76: } else {
77: llparsererror(t); /* wrong terminal on input */
78: havetoken = FALSE;
79: }
80: continue;
81: }
82:
83: /* non terminal */
84:
85: if(!havetoken) {
86: llgettoken(t);
87: havetoken = TRUE;
88: }
89:
90: /* consult parse table for new production */
91: parseaction = llfindaction(sym, t->llterm);
92:
93: if(parseaction == 0) {
94: /* error entry */
95: llparsererror(t);
96: havetoken = FALSE;
97: continue;
98: }
99:
100: if(llepsilon[parseaction]) {
101: /* epsilon production */
102: if(llepsilonok(t->llterm)) {
103: llstackptr--; /* pop nonterminal */
104: llpushprod(parseaction); /* push rhs of production */
105: } else {
106: llparsererror(t);
107: havetoken = FALSE;
108: }
109: } else {
110: llstackptr--; /* pop nonterminal */
111: llpushprod(parseaction); /* push rhs of production */
112: }
113: } while(!accepted);
114:
115: return(0);
116: }
117:
118: llpushprod(prod) /* recognize production prod - push rhs on stack */
119: short prod;
120: {
121: register start;
122: register length;
123: register count;
124:
125: start = llprodindex[prod].llprodstart;
126: length = llprodindex[prod].llprodlength;
127:
128: IFDEBUG(L)
129: printf("llpushprod(%d) llstackptr=0x%x(%d), length = 0x%x(%d)\n",
130: prod, llstackptr, llstackptr, length , length);
131: /*
132: dump_parse_stack();
133: */
134: ENDDEBUG
135: if(llstackptr+length >= STACKSIZE) {
136: fprintf(stderr,"Parse stack overflow. llstackptr=0x%x, length=0x%x\n",
137: llstackptr, length);
138: Exit(-1);
139: }
140:
141:
142: llsetattr(llprodindex[prod].llprodtlen);
143:
144: /* put a marker on the stack to mark beginning of production */
145: if(llparsestack[llstackptr] <= LLMINACTION) {
146: (llparsestack[llstackptr]) --; /* if there's already one there, don't
147: put another on; just let it represent all of
148: the adjacent markers */
149: }
150: else {
151: llstackptr++;
152: llparsestack[llstackptr] = LLMINACTION;
153: }
154:
155: for(count=0; count<length; count++) {
156: llstackptr++;
157: llparsestack[llstackptr] = llproductions[start++];
158: }
159: if(llstackptr > STACKSIZE) {
160: fprintf(stderr, "PARSE STACK OVERFLOW! \n"); Exit(-1);
161: Exit(-1);
162: }
163: }
164:
165:
166: llepsilonok(term)
167: {
168: register ptr;
169: register sym;
170: register pact;
171: register nomore;
172: register rval;
173:
174: IFDEBUG(L)
175: printf("llepsilonok() enter\n");
176: ENDDEBUG
177: rval = TRUE;
178:
179: ptr = llstackptr;
180:
181: do {
182: sym = llparsestack[ptr];
183:
184: if(sym < 0) {
185: ptr--;
186: nomore = ptr == 0;
187: continue;
188: }
189:
190: if(sym < llnterms) {
191: nomore = TRUE;
192: rval = sym == term;
193: continue;
194: }
195:
196: pact = llfindaction(sym, term);
197:
198: if(pact == 0) {
199: nomore = TRUE;
200: rval = FALSE;
201: continue;
202: }
203:
204: if(llepsilon[pact] == TRUE) {
205: ptr--;
206: nomore = ptr == 0;
207: }
208: else {
209: nomore = TRUE;
210: }
211:
212: } while(!nomore);
213:
214: return(rval);
215: }
216:
217:
218: short llfindaction(sym, term)
219: {
220: register index;
221:
222: IFDEBUG(L)
223: printf("llfindaction(sym=%d, term=%d) enter \n", sym, term);
224: ENDDEBUG
225: index = llparseindex[sym];
226:
227: while(llparsetable[index].llterm != 0) {
228: if(llparsetable[index].llterm == term) {
229: return(llparsetable[index].llprod);
230: }
231: index++;
232: }
233: return(0);
234: }
235:
236:
237: llparsererror(token)
238: LLtoken *token;
239: {
240: IFDEBUG(L)
241: fprintf(stderr,"llparsererror() enter\n");
242: prt_token(token);
243: ENDDEBUG
244:
245: fprintf(stderr, "Syntax error: ");
246: prt_token(token);
247: dump_buffer();
248: Exit(-1);
249: }
250:
251:
252: llgettoken(token)
253: LLtoken *token;
254: {
255: llscan(token);
256: token->llstate = NORMAL;
257: IFDEBUG(L)
258: printf("llgettoken(): ");
259: prt_token(token);
260: ENDDEBUG
261: }
262:
263:
264: /******************************************************************************
265:
266: Attribute support routines
267:
268: ******************************************************************************/
269: /*
270: ** attribute stack
271: **
272: ** AttrStack = stack of record
273: ** values : array of values;
274: ** ptr : index;
275: ** end;
276: **
277: */
278:
279: LLattrib llattributes[LLMAXATTR];
280: int llattrtop = 0;
281:
282: struct llattr llattrdesc[LLMAXDESC];
283:
284: int lldescindex = 1;
285:
286:
287: llsetattr(n)
288: {
289: register struct llattr *ptr;
290:
291: IFDEBUG(L)
292: printf("llsetattr(%d) enter\n",n);
293: ENDDEBUG
294: if(lldescindex >= LLMAXDESC) {
295: fprintf(stdout, "llattribute stack overflow: desc\n");
296: fprintf(stdout,
297: "lldescindex=0x%x, llattrtop=0x%x\n",lldescindex, llattrtop);
298: Exit(-1);
299: }
300: ptr = &llattrdesc[lldescindex];
301: ptr->llabase = &llattributes[llattrtop];
302: ptr->lloldtop = ++llattrtop;
303: ptr->llaindex = 1;
304: ptr->llacnt = n+1; /* the lhs ALWAYS uses an attr; it remains on the
305: stack when the production is recognized */
306: lldescindex++;
307: }
308:
309: llpushattr(attr)
310: LLattrib attr;
311: {
312: struct llattr *a;
313:
314: IFDEBUG(L)
315: printf("llpushattr() enter\n");
316: ENDDEBUG
317: if(llattrtop + 1 > LLMAXATTR) {
318: fprintf(stderr, "ATTRIBUTE STACK OVERFLOW!\n");
319: Exit(-1);
320: }
321: a = &llattrdesc[lldescindex-1];
322: llattributes[llattrtop++] = attr;
323: a->llaindex++; /* inc count of attrs on the stack for this prod */
324: }
325:
326: llfinprod()
327: {
328: IFDEBUG(L)
329: printf("llfinprod() enter\n");
330: ENDDEBUG
331: lldescindex--;
332: llattrtop = llattrdesc[lldescindex].lloldtop;
333: llattrdesc[lldescindex-1].llaindex++; /* lhs-of-prod.attr stays on
334: the stack; it is now one of the rhs attrs of the now-top production
335: on the stack */
336: }
337:
338: #ifndef LINT
339: #ifdef DEBUG
340: dump_parse_stack()
341: {
342: int ind;
343:
344: printf("PARSE STACK:\n");
345: for(ind=llstackptr; ind>=0; ind--) {
346: printf("%d\t%d\t%s\n",
347: ind, llparsestack[ind],
348: llparsestack[ind]<0? "Action symbol" : llstrings[llparsestack[ind]]);
349: }
350: }
351:
352: #endif DEBUG
353: #endif LINT
354:
355: prt_token(t)
356: LLtoken *t;
357: {
358: fprintf(stdout, "t at 0x%x\n", t);
359: fprintf(stdout, "t->llterm=0x%x\n", t->llterm); (void) fflush(stdout);
360: fprintf(stdout, "TOK: %s\n", llstrings[t->llterm]);
361: (void) fflush(stdout);
362: #ifdef LINT
363: /* to make lint shut up */
364: fprintf(stdout, "", llnterms, llnsyms, llnprods, llinfinite);
365: #endif LINT
366: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.