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 $ */
5 * Copyright (c) 1989 The Regents of the University of California.
8 * This code is derived from software contributed to Berkeley by
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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
38 extern short *itemset
;
39 extern short *itemsetend
;
40 extern unsigned *ruleset
;
45 reductions
*first_reduction
;
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);
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
;
70 static short *shift_symbol
;
73 static short *shiftset
;
75 static short **kernel_base
;
76 static short **kernel_end
;
77 static short *kernel_items
;
80 allocate_itemsets(void)
82 short *itemp
, *item_end
;
83 int i
, count
, max
, symbol
;
87 symbol_count
= NEW2(nsyms
, short);
89 item_end
= ritem
+ nitems
;
90 for (itemp
= ritem
; itemp
< item_end
; itemp
++) {
94 symbol_count
[symbol
]++;
98 kernel_base
= NEW2(nsyms
, short *);
99 kernel_items
= NEW2(count
, short);
103 for (i
= 0; i
< nsyms
; i
++) {
104 kernel_base
[i
] = kernel_items
+ count
;
105 count
+= symbol_count
[i
];
106 if (max
< symbol_count
[i
])
107 max
= symbol_count
[i
];
110 shift_symbol
= symbol_count
;
111 kernel_end
= NEW2(nsyms
, short *);
115 allocate_storage(void)
118 shiftset
= NEW2(nsyms
, short);
119 redset
= NEW2(nrules
+ 1, short);
120 state_set
= NEW2(nitems
, core
*);
129 fprintf(stderr
, "Entering append_states()\n");
131 for (i
= 1; i
< nshifts
; i
++) {
132 symbol
= shift_symbol
[i
];
134 while (j
> 0 && shift_symbol
[j
- 1] > symbol
) {
135 shift_symbol
[j
] = shift_symbol
[j
- 1];
138 shift_symbol
[j
] = symbol
;
141 for (i
= 0; i
< nshifts
; i
++) {
142 symbol
= shift_symbol
[i
];
143 shiftset
[i
] = get_state(symbol
);
161 generate_states(void)
164 itemset
= NEW2(nitems
, short);
165 ruleset
= NEW2(WORDSIZE(nrules
), unsigned);
170 closure(this_state
->items
, this_state
->nitems
);
178 this_state
= this_state
->next
;
188 get_state(int symbol
)
191 short *isp1
, *isp2
, *iend
;
195 fprintf(stderr
, "Entering get_state(%d)\n", symbol
);
198 isp1
= kernel_base
[symbol
];
199 iend
= kernel_end
[symbol
];
203 assert(0 <= key
&& key
< nitems
);
208 if (sp
->nitems
== n
) {
210 isp1
= kernel_base
[symbol
];
213 while (found
&& isp1
< iend
) {
214 if (*isp1
++ != *isp2
++)
222 sp
= sp
->link
= new_state(symbol
);
228 state_set
[key
] = sp
= new_state(symbol
);
236 initialize_states(void)
239 short *start_derives
;
242 start_derives
= derives
[start_symbol
];
243 for (i
= 0; start_derives
[i
] >= 0; ++i
)
246 p
= malloc(sizeof(core
) + i
* sizeof(short));
253 p
->accessing_symbol
= 0;
256 for (i
= 0; start_derives
[i
] >= 0; ++i
)
257 p
->items
[i
] = rrhs
[start_derives
[i
]];
259 first_state
= last_state
= this_state
= p
;
270 memset(kernel_end
, 0, nsyms
* sizeof(short *));
274 while (isp
< itemsetend
) {
278 ksp
= kernel_end
[symbol
];
280 shift_symbol
[shiftcount
++] = symbol
;
281 ksp
= kernel_base
[symbol
];
284 kernel_end
[symbol
] = ksp
;
288 nshifts
= shiftcount
;
294 new_state(int symbol
)
298 short *isp1
, *isp2
, *iend
;
301 fprintf(stderr
, "Entering new_state(%d)\n", symbol
);
304 if (nstates
>= MAXSHORT
)
305 fatal("too many states");
307 isp1
= kernel_base
[symbol
];
308 iend
= kernel_end
[symbol
];
311 p
= allocate(sizeof(core
) + (n
- 1) * sizeof(short));
312 p
->accessing_symbol
= symbol
;
320 last_state
->next
= p
;
333 short *sp1
, *sp2
, *send
;
335 p
= allocate(sizeof(shifts
) + (nshifts
- 1) * sizeof(short));
337 p
->number
= this_state
->number
;
338 p
->nshifts
= nshifts
;
342 send
= shiftset
+ nshifts
;
348 last_shift
->next
= p
;
358 save_reductions(void)
360 short *isp
, *rp1
, *rp2
;
366 for (isp
= itemset
; isp
< itemsetend
; isp
++) {
369 redset
[count
++] = -item
;
374 p
= allocate(sizeof(reductions
) + (count
- 1) * sizeof(short));
376 p
->number
= this_state
->number
;
386 if (last_reduction
) {
387 last_reduction
->next
= p
;
402 derives
= NEW2(nsyms
, short *);
403 rules
= NEW2(nvars
+ nrules
, short);
406 for (lhs
= start_symbol
; lhs
< nsyms
; lhs
++) {
407 derives
[lhs
] = rules
+ k
;
408 for (i
= 0; i
< nrules
; i
++) {
409 if (rlhs
[i
] == lhs
) {
426 free(derives
[start_symbol
]);
437 printf("\nDERIVES\n\n");
439 for (i
= start_symbol
; i
< nsyms
; i
++) {
440 printf("%s derives ", symbol_name
[i
]);
441 for (sp
= derives
[i
]; *sp
>= 0; sp
++) {
458 nullable
= calloc(1, nsyms
);
459 if (nullable
== NULL
)
465 for (i
= 1; i
< nitems
; i
++) {
467 while ((j
= ritem
[i
]) >= 0) {
483 for (i
= 0; i
< nsyms
; i
++) {
485 printf("%s is nullable\n", symbol_name
[i
]);
487 printf("%s is not nullable\n", symbol_name
[i
]);