2 * Copyright (c) 1989 The Regents of the University of California.
5 * This code is derived from software contributed to Berkeley by
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 static char sccsid
[] = "@(#)lr0.c 5.3 (Berkeley) 1/20/91";
43 extern short *itemset
;
44 extern short *itemsetend
;
45 extern unsigned *ruleset
;
50 reductions
*first_reduction
;
53 get_state (int symbol
);
56 new_state (int symbol
);
58 static core
**state_set
;
59 static core
*this_state
;
60 static core
*last_state
;
61 static shifts
*last_shift
;
62 static reductions
*last_reduction
;
65 static short *shift_symbol
;
68 static short *shiftset
;
70 static short **kernel_base
;
71 static short **kernel_end
;
72 static short *kernel_items
;
80 save_reductions (void);
89 initialize_states (void);
92 allocate_itemsets (void)
94 register short *itemp
;
95 register short *item_end
;
100 register short *symbol_count
;
103 symbol_count
= NEW2(nsyms
, short);
105 item_end
= ritem
+ nitems
;
106 for (itemp
= ritem
; itemp
< item_end
; itemp
++)
112 symbol_count
[symbol
]++;
116 kernel_base
= NEW2(nsyms
, short *);
117 kernel_items
= NEW2(count
, short);
121 for (i
= 0; i
< nsyms
; i
++)
123 kernel_base
[i
] = kernel_items
+ count
;
124 count
+= symbol_count
[i
];
125 if (max
< symbol_count
[i
])
126 max
= symbol_count
[i
];
129 shift_symbol
= symbol_count
;
130 kernel_end
= NEW2(nsyms
, short *);
134 allocate_storage (void)
137 shiftset
= NEW2(nsyms
, short);
138 redset
= NEW2(nrules
+ 1, short);
139 state_set
= NEW2(nitems
, core
*);
150 fprintf(stderr
, "Entering append_states()\n");
152 for (i
= 1; i
< nshifts
; i
++)
154 symbol
= shift_symbol
[i
];
156 while (j
> 0 && shift_symbol
[j
- 1] > symbol
)
158 shift_symbol
[j
] = shift_symbol
[j
- 1];
161 shift_symbol
[j
] = symbol
;
164 for (i
= 0; i
< nshifts
; i
++)
166 symbol
= shift_symbol
[i
];
167 shiftset
[i
] = get_state(symbol
);
184 generate_states (void)
187 itemset
= NEW2(nitems
, short);
188 ruleset
= NEW2(WORDSIZE(nrules
), unsigned);
194 closure(this_state
->items
, this_state
->nitems
);
202 this_state
= this_state
->next
;
210 get_state (int symbol
)
213 register short *isp1
;
214 register short *isp2
;
215 register short *iend
;
221 fprintf(stderr
, "Entering get_state(%d)\n", symbol
);
224 isp1
= kernel_base
[symbol
];
225 iend
= kernel_end
[symbol
];
229 assert(0 <= key
&& key
< nitems
);
239 isp1
= kernel_base
[symbol
];
242 while (found
&& isp1
< iend
)
244 if (*isp1
++ != *isp2
++)
257 sp
= sp
->link
= new_state(symbol
);
265 state_set
[key
] = sp
= new_state(symbol
);
272 initialize_states (void)
275 register short *start_derives
;
278 start_derives
= derives
[start_symbol
];
279 for (i
= 0; start_derives
[i
] >= 0; ++i
)
282 p
= (core
*) MALLOC(sizeof(core
) + i
*sizeof(short));
283 if (p
== 0) no_space();
288 p
->accessing_symbol
= 0;
291 for (i
= 0; start_derives
[i
] >= 0; ++i
)
292 p
->items
[i
] = rrhs
[start_derives
[i
]];
294 first_state
= last_state
= this_state
= p
;
302 register int shiftcount
;
307 for (i
= 0; i
< nsyms
; i
++)
312 while (isp
< itemsetend
)
318 ksp
= kernel_end
[symbol
];
321 shift_symbol
[shiftcount
++] = symbol
;
322 ksp
= kernel_base
[symbol
];
326 kernel_end
[symbol
] = ksp
;
330 nshifts
= shiftcount
;
334 new_state (int symbol
)
338 register short *isp1
;
339 register short *isp2
;
340 register short *iend
;
343 fprintf(stderr
, "Entering new_state(%d)\n", symbol
);
346 if (nstates
>= MAXSHORT
)
347 fatal("too many states");
349 isp1
= kernel_base
[symbol
];
350 iend
= kernel_end
[symbol
];
353 p
= (core
*) allocate((unsigned) (sizeof(core
) + (n
- 1) * sizeof(short)));
354 p
->accessing_symbol
= symbol
;
362 last_state
->next
= p
;
370 /* show_cores is used for debugging */
380 for (p
= first_state
; p
; ++k
, p
= p
->next
)
383 printf("state %d, number = %d, accessing symbol = %s\n",
384 k
, p
->number
, symbol_name
[p
->accessing_symbol
]);
386 for (i
= 0; i
< n
; ++i
)
388 itemno
= p
->items
[i
];
389 printf("%4d ", itemno
);
391 while (ritem
[j
] >= 0) ++j
;
392 printf("%s :", symbol_name
[rlhs
[-ritem
[j
]]]);
395 printf(" %s", symbol_name
[ritem
[j
++]]);
397 while (ritem
[j
] >= 0)
398 printf(" %s", symbol_name
[ritem
[j
++]]);
406 /* show_ritems is used for debugging */
413 for (i
= 0; i
< nitems
; ++i
)
414 printf("ritem[%d] = %d\n", i
, ritem
[i
]);
417 /* show_rrhs is used for debugging */
423 for (i
= 0; i
< nrules
; ++i
)
424 printf("rrhs[%d] = %d\n", i
, rrhs
[i
]);
428 /* show_shifts is used for debugging */
437 for (p
= first_shift
; p
; ++k
, p
= p
->next
)
440 printf("shift %d, number = %d, nshifts = %d\n", k
, p
->number
,
443 for (i
= 0; i
< j
; ++i
)
444 printf("\t%d\n", p
->shift
[i
]);
454 register short *send
;
456 p
= (shifts
*) allocate((unsigned) (sizeof(shifts
) +
457 (nshifts
- 1) * sizeof(short)));
459 p
->number
= this_state
->number
;
460 p
->nshifts
= nshifts
;
464 send
= shiftset
+ nshifts
;
471 last_shift
->next
= p
;
482 save_reductions (void)
489 register reductions
*p
;
490 register short *rend
;
493 for (isp
= itemset
; isp
< itemsetend
; isp
++)
498 redset
[count
++] = -item
;
504 p
= (reductions
*) allocate((unsigned) (sizeof(reductions
) +
505 (count
- 1) * sizeof(short)));
507 p
->number
= this_state
->number
;
519 last_reduction
->next
= p
;
535 register short *rules
;
537 derives
= NEW2(nsyms
, short *);
538 rules
= NEW2(nvars
+ nrules
, short);
541 for (lhs
= start_symbol
; lhs
< nsyms
; lhs
++)
543 derives
[lhs
] = rules
+ k
;
544 for (i
= 0; i
< nrules
; i
++)
565 FREE(derives
[start_symbol
]);
577 printf("\nDERIVES\n\n");
579 for (i
= start_symbol
; i
< nsyms
; i
++)
581 printf("%s derives ", symbol_name
[i
]);
582 for (sp
= derives
[i
]; *sp
>= 0; sp
++)
600 nullable
= (char*)MALLOC(nsyms
);
601 if (nullable
== 0) no_space();
603 for (i
= 0; i
< nsyms
; ++i
)
610 for (i
= 1; i
< nitems
; i
++)
613 while ((j
= ritem
[i
]) >= 0)
632 for (i
= 0; i
< nsyms
; i
++)
635 printf("%s is nullable\n", symbol_name
[i
]);
637 printf("%s is not nullable\n", symbol_name
[i
]);