GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/yacc/lr0.c Lines: 190 193 98.4 %
Date: 2017-11-13 Branches: 85 90 94.4 %

Line Branch Exec Source
1
/* $OpenBSD: lr0.c,v 1.18 2014/03/13 01:18:22 tedu Exp $	 */
2
/* $NetBSD: lr0.c,v 1.4 1996/03/19 03:21:35 jtc Exp $	 */
3
4
/*
5
 * Copyright (c) 1989 The Regents of the University of California.
6
 * All rights reserved.
7
 *
8
 * This code is derived from software contributed to Berkeley by
9
 * Robert Paul Corbett.
10
 *
11
 * Redistribution and use in source and binary forms, with or without
12
 * modification, are permitted provided that the following conditions
13
 * are met:
14
 * 1. Redistributions of source code must retain the above copyright
15
 *    notice, this list of conditions and the following disclaimer.
16
 * 2. Redistributions in binary form must reproduce the above copyright
17
 *    notice, this list of conditions and the following disclaimer in the
18
 *    documentation and/or other materials provided with the distribution.
19
 * 3. Neither the name of the University nor the names of its contributors
20
 *    may be used to endorse or promote products derived from this software
21
 *    without specific prior written permission.
22
 *
23
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33
 * SUCH DAMAGE.
34
 */
35
36
#include "defs.h"
37
38
extern short *itemset;
39
extern short *itemsetend;
40
extern unsigned *ruleset;
41
42
int nstates;
43
core *first_state;
44
shifts *first_shift;
45
reductions *first_reduction;
46
47
short get_state(int);
48
core *new_state(int);
49
50
void allocate_itemsets(void);
51
void allocate_storage(void);
52
void append_states(void);
53
void free_storage(void);
54
void generate_states(void);
55
void initialize_states(void);
56
void new_itemsets(void);
57
void save_shifts(void);
58
void save_reductions(void);
59
void set_derives(void);
60
void print_derives(void);
61
void set_nullable(void);
62
63
static core **state_set;
64
static core *this_state;
65
static core *last_state;
66
static shifts *last_shift;
67
static reductions *last_reduction;
68
69
static int nshifts;
70
static short *shift_symbol;
71
72
static short *redset;
73
static short *shiftset;
74
75
static short **kernel_base;
76
static short **kernel_end;
77
static short *kernel_items;
78
79
void
80
allocate_itemsets(void)
81
{
82
	short *itemp, *item_end;
83
	int i, count, max, symbol;
84
	short *symbol_count;
85
86
	count = 0;
87
18
	symbol_count = NEW2(nsyms, short);
88
89
9
	item_end = ritem + nitems;
90
6976
	for (itemp = ritem; itemp < item_end; itemp++) {
91
3479
		symbol = *itemp;
92
3479
		if (symbol >= 0) {
93
2567
			count++;
94
2567
			symbol_count[symbol]++;
95
2567
		}
96
	}
97
98
9
	kernel_base = NEW2(nsyms, short *);
99
9
	kernel_items = NEW2(count, short);
100
101
	count = 0;
102
	max = 0;
103
1716
	for (i = 0; i < nsyms; i++) {
104
849
		kernel_base[i] = kernel_items + count;
105
849
		count += symbol_count[i];
106
849
		if (max < symbol_count[i])
107
43
			max = symbol_count[i];
108
	}
109
110
9
	shift_symbol = symbol_count;
111
9
	kernel_end = NEW2(nsyms, short *);
112
9
}
113
114
void
115
allocate_storage(void)
116
{
117
18
	allocate_itemsets();
118
9
	shiftset = NEW2(nsyms, short);
119
9
	redset = NEW2(nrules + 1, short);
120
9
	state_set = NEW2(nitems, core *);
121
9
}
122
123
void
124
append_states(void)
125
{
126
	int i, j, symbol;
127
128
#ifdef	TRACE
129
	fprintf(stderr, "Entering append_states()\n");
130
#endif
131
13696
	for (i = 1; i < nshifts; i++) {
132
3644
		symbol = shift_symbol[i];
133
		j = i;
134

66350
		while (j > 0 && shift_symbol[j - 1] > symbol) {
135
18767
			shift_symbol[j] = shift_symbol[j - 1];
136
18767
			j--;
137
		}
138
3644
		shift_symbol[j] = symbol;
139
	}
140
141
14460
	for (i = 0; i < nshifts; i++) {
142
5094
		symbol = shift_symbol[i];
143
5094
		shiftset[i] = get_state(symbol);
144
	}
145
2136
}
146
147
void
148
free_storage(void)
149
{
150
18
	free(shift_symbol);
151
9
	free(redset);
152
9
	free(shiftset);
153
9
	free(kernel_base);
154
9
	free(kernel_end);
155
9
	free(kernel_items);
156
9
	free(state_set);
157
9
}
158
159
160
void
161
generate_states(void)
162
{
163
18
	allocate_storage();
164
9
	itemset = NEW2(nitems, short);
165
9
	ruleset = NEW2(WORDSIZE(nrules), unsigned);
166
9
	set_first_derives();
167
9
	initialize_states();
168
169
4290
	while (this_state) {
170
2136
		closure(this_state->items, this_state->nitems);
171
2136
		save_reductions();
172
2136
		new_itemsets();
173
2136
		append_states();
174
175
2136
		if (nshifts > 0)
176
1450
			save_shifts();
177
178
2136
		this_state = this_state->next;
179
	}
180
181
9
	finalize_closure();
182
9
	free_storage();
183
9
}
184
185
186
187
short
188
get_state(int symbol)
189
{
190
	int n, found, key;
191
	short *isp1, *isp2, *iend;
192
	core *sp;
193
194
#ifdef	TRACE
195
	fprintf(stderr, "Entering get_state(%d)\n", symbol);
196
#endif
197
198
10188
	isp1 = kernel_base[symbol];
199
5094
	iend = kernel_end[symbol];
200
5094
	n = iend - isp1;
201
202
5094
	key = *isp1;
203

10188
	assert(0 <= key && key < nitems);
204
5094
	sp = state_set[key];
205
5094
	if (sp) {
206
		found = 0;
207
12648
		while (!found) {
208
3275
			if (sp->nitems == n) {
209
				found = 1;
210
3155
				isp1 = kernel_base[symbol];
211
3155
				isp2 = sp->items;
212
213

22816
				while (found && isp1 < iend) {
214
4513
					if (*isp1++ != *isp2++)
215
188
						found = 0;
216
				}
217
			}
218
3275
			if (!found) {
219
308
				if (sp->link) {
220
					sp = sp->link;
221
226
				} else {
222
82
					sp = sp->link = new_state(symbol);
223
					found = 1;
224
				}
225
			}
226
		}
227
	} else {
228
2045
		state_set[key] = sp = new_state(symbol);
229
	}
230
231
5094
	return (sp->number);
232
}
233
234
235
void
236
initialize_states(void)
237
{
238
	int i;
239
	short *start_derives;
240
	core *p;
241
242
18
	start_derives = derives[start_symbol];
243
36
	for (i = 0; start_derives[i] >= 0; ++i)
244
		continue;
245
246
9
	p = malloc(sizeof(core) + i * sizeof(short));
247
9
	if (p == NULL)
248
		no_space();
249
250
9
	p->next = 0;
251
9
	p->link = 0;
252
9
	p->number = 0;
253
9
	p->accessing_symbol = 0;
254
9
	p->nitems = i;
255
256
36
	for (i = 0; start_derives[i] >= 0; ++i)
257
9
		p->items[i] = rrhs[start_derives[i]];
258
259
9
	first_state = last_state = this_state = p;
260
9
	nstates = 1;
261
9
}
262
263
void
264
new_itemsets(void)
265
{
266
	int i, shiftcount;
267
	short *isp, *ksp;
268
	int symbol;
269
270
4272
	memset(kernel_end, 0, nsyms * sizeof(short *));
271
272
	shiftcount = 0;
273
2136
	isp = itemset;
274
20462
	while (isp < itemsetend) {
275
8095
		i = *isp++;
276
8095
		symbol = ritem[i];
277
8095
		if (symbol > 0) {
278
7005
			ksp = kernel_end[symbol];
279
7005
			if (!ksp) {
280
5094
				shift_symbol[shiftcount++] = symbol;
281
5094
				ksp = kernel_base[symbol];
282
5094
			}
283
7005
			*ksp++ = i + 1;
284
7005
			kernel_end[symbol] = ksp;
285
7005
		}
286
	}
287
288
2136
	nshifts = shiftcount;
289
2136
}
290
291
292
293
core *
294
new_state(int symbol)
295
{
296
	int n;
297
	core *p;
298
	short *isp1, *isp2, *iend;
299
300
#ifdef	TRACE
301
	fprintf(stderr, "Entering new_state(%d)\n", symbol);
302
#endif
303
304
4254
	if (nstates >= MAXSHORT)
305
		fatal("too many states");
306
307
2127
	isp1 = kernel_base[symbol];
308
2127
	iend = kernel_end[symbol];
309
2127
	n = iend - isp1;
310
311
2127
	p = allocate(sizeof(core) + (n - 1) * sizeof(short));
312
2127
	p->accessing_symbol = symbol;
313
2127
	p->number = nstates;
314
2127
	p->nitems = n;
315
316
2127
	isp2 = p->items;
317
10722
	while (isp1 < iend)
318
3234
		*isp2++ = *isp1++;
319
320
2127
	last_state->next = p;
321
2127
	last_state = p;
322
323
2127
	nstates++;
324
325
2127
	return (p);
326
}
327
328
329
void
330
save_shifts(void)
331
{
332
	shifts *p;
333
	short *sp1, *sp2, *send;
334
335
2900
	p = allocate(sizeof(shifts) + (nshifts - 1) * sizeof(short));
336
337
1450
	p->number = this_state->number;
338
1450
	p->nshifts = nshifts;
339
340
1450
	sp1 = shiftset;
341
1450
	sp2 = p->shift;
342
1450
	send = shiftset + nshifts;
343
344
13088
	while (sp1 < send)
345
5094
		*sp2++ = *sp1++;
346
347
1450
	if (last_shift) {
348
1441
		last_shift->next = p;
349
		last_shift = p;
350
1441
	} else {
351
9
		first_shift = p;
352
		last_shift = p;
353
	}
354
1450
}
355
356
357
void
358
save_reductions(void)
359
{
360
	short *isp, *rp1, *rp2;
361
	int item, count;
362
	reductions *p;
363
	short *rend;
364
365
	count = 0;
366
22598
	for (isp = itemset; isp < itemsetend; isp++) {
367
8095
		item = ritem[*isp];
368
8095
		if (item < 0) {
369
1081
			redset[count++] = -item;
370
1081
		}
371
	}
372
373
2136
	if (count) {
374
1071
		p = allocate(sizeof(reductions) + (count - 1) * sizeof(short));
375
376
1071
		p->number = this_state->number;
377
1071
		p->nreds = count;
378
379
1071
		rp1 = redset;
380
1071
		rp2 = p->rules;
381
1071
		rend = rp1 + count;
382
383
4304
		while (rp1 < rend)
384
1081
			*rp2++ = *rp1++;
385
386
1071
		if (last_reduction) {
387
1062
			last_reduction->next = p;
388
			last_reduction = p;
389
1062
		} else {
390
9
			first_reduction = p;
391
			last_reduction = p;
392
		}
393
1071
	}
394
2136
}
395
396
void
397
set_derives(void)
398
{
399
	int i, k, lhs;
400
	short *rules;
401
402
18
	derives = NEW2(nsyms, short *);
403
9
	rules = NEW2(nvars + nrules, short);
404
405
	k = 0;
406
498
	for (lhs = start_symbol; lhs < nsyms; lhs++) {
407
240
		derives[lhs] = rules + k;
408
51432
		for (i = 0; i < nrules; i++) {
409
25476
			if (rlhs[i] == lhs) {
410
903
				rules[k] = i;
411
903
				k++;
412
903
			}
413
		}
414
240
		rules[k] = -1;
415
240
		k++;
416
	}
417
418
#ifdef	DEBUG
419
	print_derives();
420
#endif
421
9
}
422
423
void
424
free_derives(void)
425
{
426
18
	free(derives[start_symbol]);
427
9
	free(derives);
428
9
}
429
430
#ifdef	DEBUG
431
void
432
print_derives(void)
433
{
434
	int i;
435
	short *sp;
436
437
	printf("\nDERIVES\n\n");
438
439
	for (i = start_symbol; i < nsyms; i++) {
440
		printf("%s derives ", symbol_name[i]);
441
		for (sp = derives[i]; *sp >= 0; sp++) {
442
			printf("  %d", *sp);
443
		}
444
		putchar('\n');
445
	}
446
447
	putchar('\n');
448
}
449
#endif
450
451
void
452
set_nullable(void)
453
{
454
	int i, j;
455
	int empty;
456
	int done;
457
458
18
	nullable = calloc(1, nsyms);
459
9
	if (nullable == NULL)
460
		no_space();
461
462
	done = 0;
463
62
	while (!done) {
464
		done = 1;
465
4592
		for (i = 1; i < nitems; i++) {
466
			empty = 1;
467
16540
			while ((j = ritem[i]) >= 0) {
468
5996
				if (!nullable[j])
469
5583
					empty = 0;
470
5996
				++i;
471
			}
472
2274
			if (empty) {
473
168
				j = rlhs[-j];
474
168
				if (!nullable[j]) {
475
64
					nullable[j] = 1;
476
					done = 0;
477
64
				}
478
			}
479
		}
480
	}
481
482
#ifdef DEBUG
483
	for (i = 0; i < nsyms; i++) {
484
		if (nullable[i])
485
			printf("%s is nullable\n", symbol_name[i]);
486
		else
487
			printf("%s is not nullable\n", symbol_name[i]);
488
	}
489
#endif
490
9
}
491
492
void
493
free_nullable(void)
494
{
495
18
	free(nullable);
496
9
}
497
498
void
499
lr0(void)
500
{
501
18
	set_derives();
502
9
	set_nullable();
503
9
	generate_states();
504
9
}