|
|
1.1 root 1: /*
2: * Copyright (c) 1989 The Regents of the University of California.
3: * All rights reserved.
4: *
5: * This code is derived from software contributed to Berkeley by
6: * Robert Paul Corbett.
7: *
8: * Redistribution and use in source and binary forms are permitted provided
9: * that: (1) source distributions retain this entire copyright notice and
10: * comment, and (2) distributions including binaries display the following
11: * acknowledgement: ``This product includes software developed by the
12: * University of California, Berkeley and its contributors'' in the
13: * documentation or other materials provided with the distribution and in
14: * all advertising materials mentioning features or use of this software.
15: * Neither the name of the University nor the names of its contributors may
16: * be used to endorse or promote products derived from this software without
17: * specific prior written permission.
18: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
19: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
20: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21: */
22:
23: #ifndef lint
24: static char sccsid[] = "@(#)mkpar.c 5.2 (Berkeley) 6/1/90";
25: #endif /* not lint */
26:
27: #include "defs.h"
28:
29: action **parser;
30: int SRtotal;
31: int RRtotal;
32: short *SRconflicts;
33: short *RRconflicts;
34: short *defred;
35: short *rules_used;
36: short nunused;
37: short final_state;
38:
39: static int SRcount;
40: static int RRcount;
41:
42: extern action *parse_actions();
43: extern action *get_shifts();
44: extern action *add_reductions();
45: extern action *add_reduce();
46:
47:
48: make_parser()
49: {
50: register int i;
51:
52: parser = NEW2(nstates, action *);
53: for (i = 0; i < nstates; i++)
54: parser[i] = parse_actions(i);
55:
56: find_final_state();
57: remove_conflicts();
58: unused_rules();
59: if (SRtotal + RRtotal > 0) total_conflicts();
60: defreds();
61: }
62:
63:
64: action *
65: parse_actions(stateno)
66: register int stateno;
67: {
68: register action *actions;
69:
70: actions = get_shifts(stateno);
71: actions = add_reductions(stateno, actions);
72: return (actions);
73: }
74:
75:
76: action *
77: get_shifts(stateno)
78: int stateno;
79: {
80: register action *actions, *temp;
81: register shifts *sp;
82: register short *to_state;
83: register int i, k;
84: register int symbol;
85:
86: actions = 0;
87: sp = shift_table[stateno];
88: if (sp)
89: {
90: to_state = sp->shift;
91: for (i = sp->nshifts - 1; i >= 0; i--)
92: {
93: k = to_state[i];
94: symbol = accessing_symbol[k];
95: if (ISTOKEN(symbol))
96: {
97: temp = NEW(action);
98: temp->next = actions;
99: temp->symbol = symbol;
100: temp->number = k;
101: temp->prec = symbol_prec[symbol];
102: temp->action_code = SHIFT;
103: temp->assoc = symbol_assoc[symbol];
104: actions = temp;
105: }
106: }
107: }
108: return (actions);
109: }
110:
111: action *
112: add_reductions(stateno, actions)
113: int stateno;
114: register action *actions;
115: {
116: register int i, j, m, n;
117: register int ruleno, tokensetsize;
118: register unsigned *rowp;
119:
120: tokensetsize = WORDSIZE(ntokens);
121: m = lookaheads[stateno];
122: n = lookaheads[stateno + 1];
123: for (i = m; i < n; i++)
124: {
125: ruleno = LAruleno[i];
126: rowp = LA + i * tokensetsize;
127: for (j = ntokens - 1; j >= 0; j--)
128: {
129: if (BIT(rowp, j))
130: actions = add_reduce(actions, ruleno, j);
131: }
132: }
133: return (actions);
134: }
135:
136:
137: action *
138: add_reduce(actions, ruleno, symbol)
139: register action *actions;
140: register int ruleno, symbol;
141: {
142: register action *temp, *prev, *next;
143:
144: prev = 0;
145: for (next = actions; next && next->symbol < symbol; next = next->next)
146: prev = next;
147:
148: while (next && next->symbol == symbol && next->action_code == SHIFT)
149: {
150: prev = next;
151: next = next->next;
152: }
153:
154: while (next && next->symbol == symbol &&
155: next->action_code == REDUCE && next->number < ruleno)
156: {
157: prev = next;
158: next = next->next;
159: }
160:
161: temp = NEW(action);
162: temp->next = next;
163: temp->symbol = symbol;
164: temp->number = ruleno;
165: temp->prec = rprec[ruleno];
166: temp->action_code = REDUCE;
167: temp->assoc = rassoc[ruleno];
168:
169: if (prev)
170: prev->next = temp;
171: else
172: actions = temp;
173:
174: return (actions);
175: }
176:
177:
178: find_final_state()
179: {
180: register int goal, i;
181: register short *to_state;
182: register shifts *p;
183:
184: p = shift_table[0];
185: to_state = p->shift;
186: goal = ritem[1];
187: for (i = p->nshifts - 1; i >= 0; --i)
188: {
189: final_state = to_state[i];
190: if (accessing_symbol[final_state] == goal) break;
191: }
192: }
193:
194:
195: unused_rules()
196: {
197: register int i;
198: register action *p;
199:
200: rules_used = (short *) MALLOC(nrules*sizeof(short));
201: if (rules_used == 0) no_space();
202:
203: for (i = 0; i < nrules; ++i)
204: rules_used[i] = 0;
205:
206: for (i = 0; i < nstates; ++i)
207: {
208: for (p = parser[i]; p; p = p->next)
209: {
210: if (p->action_code == REDUCE && p->suppressed == 0)
211: rules_used[p->number] = 1;
212: }
213: }
214:
215: nunused = 0;
216: for (i = 3; i < nrules; ++i)
217: if (!rules_used[i]) ++nunused;
218:
219: if (nunused)
220: if (nunused == 1)
221: fprintf(stderr, "%s: 1 rule never reduced\n", myname);
222: else
223: fprintf(stderr, "%s: %d rules never reduced\n", myname, nunused);
224: }
225:
226:
227: remove_conflicts()
228: {
229: register int i;
230: register int symbol;
231: register action *p, *q;
232:
233: SRtotal = 0;
234: RRtotal = 0;
235: SRconflicts = NEW2(nstates, short);
236: RRconflicts = NEW2(nstates, short);
237: for (i = 0; i < nstates; i++)
238: {
239: SRcount = 0;
240: RRcount = 0;
241: for (p = parser[i]; p; p = q->next)
242: {
243: symbol = p->symbol;
244: q = p;
245: while (q->next && q->next->symbol == symbol)
246: q = q->next;
247: if (i == final_state && symbol == 0)
248: end_conflicts(p, q);
249: else if (p != q)
250: resolve_conflicts(p, q);
251: }
252: SRtotal += SRcount;
253: RRtotal += RRcount;
254: SRconflicts[i] = SRcount;
255: RRconflicts[i] = RRcount;
256: }
257: }
258:
259:
260: end_conflicts(p, q)
261: register action *p, *q;
262: {
263: for (;;)
264: {
265: SRcount++;
266: p->suppressed = 1;
267: if (p == q) break;
268: p = p->next;
269: }
270: }
271:
272:
273: resolve_conflicts(first, last)
274: register action *first, *last;
275: {
276: register action *p;
277: register int count;
278:
279: count = 1;
280: for (p = first; p != last; p = p->next)
281: ++count;
282: assert(count > 1);
283:
284: if (first->action_code == SHIFT && count == 2 &&
285: first->prec > 0 && last->prec > 0)
286: {
287: if (first->prec == last->prec)
288: {
289: if (first->assoc == LEFT)
290: first->suppressed = 2;
291: else if (first->assoc == RIGHT)
292: last->suppressed = 2;
293: else
294: {
295: first->suppressed = 2;
296: last->suppressed = 2;
297: first->action_code = ERROR;
298: last->action_code = ERROR;
299: }
300: }
301: else if (first->prec < last->prec)
302: first->suppressed = 2;
303: else
304: last->suppressed = 2;
305: }
306: else
307: {
308: if (first->action_code == SHIFT)
309: SRcount += (count - 1);
310: else
311: RRcount += (count - 1);
312: for (p = first; p != last; p = p->next, p->suppressed = 1)
313: continue;
314: }
315: }
316:
317:
318: total_conflicts()
319: {
320: fprintf(stderr, "%s: ", myname);
321: if (SRtotal == 1)
322: fprintf(stderr, "1 shift/reduce conflict");
323: else if (SRtotal > 1)
324: fprintf(stderr, "%d shift/reduce conflicts", SRtotal);
325:
326: if (SRtotal && RRtotal)
327: fprintf(stderr, ", ");
328:
329: if (RRtotal == 1)
330: fprintf(stderr, "1 reduce/reduce conflict");
331: else if (RRtotal > 1)
332: fprintf(stderr, "%d reduce/reduce conflicts", RRtotal);
333:
334: fprintf(stderr, ".\n");
335: }
336:
337:
338: int
339: sole_reduction(stateno)
340: int stateno;
341: {
342: register int count, ruleno;
343: register action *p;
344:
345: count = 0;
346: ruleno = 0;
347: for (p = parser[stateno]; p; p = p->next)
348: {
349: if (p->action_code == SHIFT && p->suppressed == 0)
350: return (0);
351: else if (p->action_code == REDUCE && p->suppressed == 0)
352: {
353: if (ruleno > 0 && p->number != ruleno)
354: return (0);
355: if (p->symbol != 1)
356: ++count;
357: ruleno = p->number;
358: }
359: }
360:
361: if (count == 0)
362: return (0);
363: return (ruleno);
364: }
365:
366:
367: defreds()
368: {
369: register int i;
370:
371: defred = NEW2(nstates, short);
372: for (i = 0; i < nstates; i++)
373: defred[i] = sole_reduction(i);
374: }
375:
376: free_action_row(p)
377: register action *p;
378: {
379: register action *q;
380:
381: while (p)
382: {
383: q = p->next;
384: FREE(p);
385: p = q;
386: }
387: }
388:
389: free_parser()
390: {
391: register int i;
392:
393: for (i = 0; i < nstates; i++)
394: free_action_row(parser[i]);
395:
396: FREE(parser);
397: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.