1 /* $NetBSD: lr0.c,v 1.9 2006/05/24 18:01:43 christos Exp $ */
4 * Copyright (c) 1989 The Regents of the University of California.
7 * This code is derived from software contributed to Berkeley by
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 #include <sys/cdefs.h>
36 #if defined(__RCSID) && !defined(lint)
38 static char sccsid
[] = "@(#)lr0.c 5.3 (Berkeley) 1/20/91";
40 __RCSID("$NetBSD: lr0.c,v 1.9 2006/05/24 18:01:43 christos Exp $");
46 extern short *itemset
;
47 extern short *itemsetend
;
48 extern unsigned *ruleset
;
53 reductions
*first_reduction
;
55 static int get_state(int);
56 static core
*new_state(int);
58 static void allocate_itemsets(void);
59 static void allocate_storage(void);
60 static void append_states(void);
61 static void free_storage(void);
62 static void generate_states(void);
63 static void initialize_states(void);
64 static void new_itemsets(void);
66 static void show_cores(void);
67 static void show_ritems(void);
68 static void show_rrhs(void);
69 static void show_shifts(void);
71 static void save_shifts(void);
72 static void save_reductions(void);
73 static void set_derives(void);
74 static void set_nullable(void);
76 static void print_derives(void);
77 static void free_derives(void);
78 static void free_nullable(void);
81 static core
**state_set
;
82 static core
*this_state
;
83 static core
*last_state
;
84 static shifts
*last_shift
;
85 static reductions
*last_reduction
;
88 static short *shift_symbol
;
91 static short *shiftset
;
93 static short **kernel_base
;
94 static short **kernel_end
;
95 static short *kernel_items
;
98 allocate_itemsets(void)
109 symbol_count
= NEW2(nsyms
, short);
111 item_end
= ritem
+ nitems
;
112 for (itemp
= ritem
; itemp
< item_end
; itemp
++)
118 symbol_count
[symbol
]++;
122 kernel_base
= NEW2(nsyms
, short *);
123 kernel_items
= NEW2(count
, short);
127 for (i
= 0; i
< nsyms
; i
++)
129 kernel_base
[i
] = kernel_items
+ count
;
130 count
+= symbol_count
[i
];
131 if (max
< symbol_count
[i
])
132 max
= symbol_count
[i
];
135 shift_symbol
= symbol_count
;
136 kernel_end
= NEW2(nsyms
, short *);
140 allocate_storage(void)
143 shiftset
= NEW2(nsyms
, short);
144 redset
= NEW2(nrules
+ 1, short);
145 state_set
= NEW2(nitems
, core
*);
156 fprintf(stderr
, "Entering append_states()\n");
158 for (i
= 1; i
< nshifts
; i
++)
160 symbol
= shift_symbol
[i
];
162 while (j
> 0 && shift_symbol
[j
- 1] > symbol
)
164 shift_symbol
[j
] = shift_symbol
[j
- 1];
167 shift_symbol
[j
] = symbol
;
170 for (i
= 0; i
< nshifts
; i
++)
172 symbol
= shift_symbol
[i
];
173 shiftset
[i
] = get_state(symbol
);
191 generate_states(void)
194 itemset
= NEW2(nitems
, short);
195 ruleset
= NEW2(WORDSIZE(nrules
), unsigned);
201 closure(this_state
->items
, this_state
->nitems
);
209 this_state
= this_state
->next
;
219 get_state(int symbol
)
230 fprintf(stderr
, "Entering get_state(%d)\n", symbol
);
233 isp1
= kernel_base
[symbol
];
234 iend
= kernel_end
[symbol
];
238 assert(0 <= key
&& key
< nitems
);
248 isp1
= kernel_base
[symbol
];
251 while (found
&& isp1
< iend
)
253 if (*isp1
++ != *isp2
++)
266 sp
= sp
->link
= new_state(symbol
);
274 state_set
[key
] = sp
= new_state(symbol
);
282 initialize_states(void)
285 short *start_derives
;
288 start_derives
= derives
[start_symbol
];
289 for (i
= 0; start_derives
[i
] >= 0; ++i
)
292 p
= (core
*) MALLOC(sizeof(core
) + i
*sizeof(short));
293 if (p
== 0) no_space();
298 p
->accessing_symbol
= 0;
301 for (i
= 0; start_derives
[i
] >= 0; ++i
)
302 p
->items
[i
] = rrhs
[start_derives
[i
]];
304 first_state
= last_state
= this_state
= p
;
318 for (i
= 0; i
< nsyms
; i
++)
323 while (isp
< itemsetend
)
329 ksp
= kernel_end
[symbol
];
332 shift_symbol
[shiftcount
++] = symbol
;
333 ksp
= kernel_base
[symbol
];
337 kernel_end
[symbol
] = ksp
;
341 nshifts
= shiftcount
;
347 new_state(int symbol
)
356 fprintf(stderr
, "Entering new_state(%d)\n", symbol
);
359 if (nstates
>= MAXSHORT
)
360 fatal("too many states");
362 isp1
= kernel_base
[symbol
];
363 iend
= kernel_end
[symbol
];
366 p
= (core
*) allocate((unsigned) (sizeof(core
) + (n
- 1) * sizeof(short)));
367 p
->accessing_symbol
= symbol
;
375 last_state
->next
= p
;
384 /* show_cores is used for debugging */
393 for (p
= first_state
; p
; ++k
, p
= p
->next
)
396 printf("state %d, number = %d, accessing symbol = %s\n",
397 k
, p
->number
, symbol_name
[p
->accessing_symbol
]);
399 for (i
= 0; i
< n
; ++i
)
401 itemno
= p
->items
[i
];
402 printf("%4d ", itemno
);
404 while (ritem
[j
] >= 0) ++j
;
405 printf("%s :", symbol_name
[rlhs
[-ritem
[j
]]]);
408 printf(" %s", symbol_name
[ritem
[j
++]]);
410 while (ritem
[j
] >= 0)
411 printf(" %s", symbol_name
[ritem
[j
++]]);
419 /* show_ritems is used for debugging */
425 for (i
= 0; i
< nitems
; ++i
)
426 printf("ritem[%d] = %d\n", i
, ritem
[i
]);
430 /* show_rrhs is used for debugging */
436 for (i
= 0; i
< nrules
; ++i
)
437 printf("rrhs[%d] = %d\n", i
, rrhs
[i
]);
441 /* show_shifts is used for debugging */
449 for (p
= first_shift
; p
; ++k
, p
= p
->next
)
452 printf("shift %d, number = %d, nshifts = %d\n", k
, p
->number
,
455 for (i
= 0; i
< j
; ++i
)
456 printf("\t%d\n", p
->shift
[i
]);
470 p
= (shifts
*) allocate((unsigned) (sizeof(shifts
) +
471 (nshifts
- 1) * sizeof(short)));
473 p
->number
= this_state
->number
;
474 p
->nshifts
= nshifts
;
478 send
= shiftset
+ nshifts
;
485 last_shift
->next
= p
;
497 save_reductions(void)
508 for (isp
= itemset
; isp
< itemsetend
; isp
++)
513 redset
[count
++] = -item
;
519 p
= (reductions
*) allocate((unsigned) (sizeof(reductions
) +
520 (count
- 1) * sizeof(short)));
522 p
->number
= this_state
->number
;
534 last_reduction
->next
= p
;
553 derives
= NEW2(nsyms
, short *);
554 if (start_symbol
>= nsyms
)
557 rules
= NEW2(nvars
+ nrules
, short);
560 for (lhs
= start_symbol
; lhs
< nsyms
; lhs
++)
562 derives
[lhs
] = rules
+ k
;
563 for (i
= 0; i
< nrules
; i
++)
584 FREE(derives
[start_symbol
]);
596 printf("\nDERIVES\n\n");
598 for (i
= start_symbol
; i
< nsyms
; i
++)
600 printf("%s derives ", symbol_name
[i
]);
601 for (sp
= derives
[i
]; *sp
>= 0; sp
++)
620 nullable
= MALLOC(nsyms
);
621 if (nullable
== 0) no_space();
623 for (i
= 0; i
< nsyms
; ++i
)
630 for (i
= 1; i
< nitems
; i
++)
633 while ((j
= ritem
[i
]) >= 0)
652 for (i
= 0; i
< nsyms
; i
++)
655 printf("%s is nullable\n", symbol_name
[i
]);
657 printf("%s is not nullable\n", symbol_name
[i
]);