Berkeley YACC  1993-03-03
Berkeley's version of Yet Another Compiler Compiler
 All Data Structures Files Functions Variables Typedefs Macros Groups
lr0.c
Go to the documentation of this file.
1 
2 #include "defs.h"
3 
4 extern short *itemset;
5 extern short *itemsetend;
6 extern unsigned *ruleset;
7 
8 int nstates;
12 
13 int get_state();
14 core *new_state();
15 
16 static core **state_set;
17 static core *this_state;
18 static core *last_state;
21 
22 static int nshifts;
23 static short *shift_symbol;
24 
25 static short *redset;
26 static short *shiftset;
27 
28 static short **kernel_base;
29 static short **kernel_end;
30 static short *kernel_items;
31 
32 
34 {
35  register short *itemp;
36  register short *item_end;
37  register int symbol;
38  register int i;
39  register int count;
40  register int max;
41  register short *symbol_count;
42 
43  count = 0;
44  symbol_count = NEW2(nsyms, short);
45 
46  item_end = ritem + nitems;
47  for (itemp = ritem; itemp < item_end; itemp++)
48  {
49  symbol = *itemp;
50  if (symbol >= 0)
51  {
52  count++;
53  symbol_count[symbol]++;
54  }
55  }
56 
57  kernel_base = NEW2(nsyms, short *);
58  kernel_items = NEW2(count, short);
59 
60  count = 0;
61  max = 0;
62  for (i = 0; i < nsyms; i++)
63  {
64  kernel_base[i] = kernel_items + count;
65  count += symbol_count[i];
66  if (max < symbol_count[i])
67  max = symbol_count[i];
68  }
69 
70  shift_symbol = symbol_count;
71  kernel_end = NEW2(nsyms, short *);
72 }
73 
74 
76 {
78  shiftset = NEW2(nsyms, short);
79  redset = NEW2(nrules + 1, short);
80  state_set = NEW2(nitems, core *);
81 }
82 
83 
85 {
86  register int i;
87  register int j;
88  register int symbol;
89 
90 #ifdef TRACE
91  fprintf(stderr, "Entering append_states()\n");
92 #endif
93  for (i = 1; i < nshifts; i++)
94  {
95  symbol = shift_symbol[i];
96  j = i;
97  while (j > 0 && shift_symbol[j - 1] > symbol)
98  {
99  shift_symbol[j] = shift_symbol[j - 1];
100  j--;
101  }
102  shift_symbol[j] = symbol;
103  }
104 
105  for (i = 0; i < nshifts; i++)
106  {
107  symbol = shift_symbol[i];
108  shiftset[i] = get_state(symbol);
109  }
110 }
111 
112 
114 {
116  FREE(redset);
117  FREE(shiftset);
118  FREE(kernel_base);
119  FREE(kernel_end);
121  FREE(state_set);
122 }
123 
124 
125 
127 {
129  itemset = NEW2(nitems, short);
130  ruleset = NEW2(WORDSIZE(nrules), unsigned);
133 
134  while (this_state)
135  {
136  closure(this_state->items, this_state->nitems);
137  save_reductions();
138  new_itemsets();
139  append_states();
140 
141  if (nshifts > 0)
142  save_shifts();
143 
144  this_state = this_state->next;
145  }
146 
148  free_storage();
149 }
150 
151 
152 
153 int
154 get_state(symbol)
155 int symbol;
156 {
157  register int key;
158  register short *isp1;
159  register short *isp2;
160  register short *iend;
161  register core *sp;
162  register int found;
163  register int n;
164 
165 #ifdef TRACE
166  fprintf(stderr, "Entering get_state(%d)\n", symbol);
167 #endif
168 
169  isp1 = kernel_base[symbol];
170  iend = kernel_end[symbol];
171  n = iend - isp1;
172 
173  key = *isp1;
174  assert(0 <= key && key < nitems);
175  sp = state_set[key];
176  if (sp)
177  {
178  found = 0;
179  while (!found)
180  {
181  if (sp->nitems == n)
182  {
183  found = 1;
184  isp1 = kernel_base[symbol];
185  isp2 = sp->items;
186 
187  while (found && isp1 < iend)
188  {
189  if (*isp1++ != *isp2++)
190  found = 0;
191  }
192  }
193 
194  if (!found)
195  {
196  if (sp->link)
197  {
198  sp = sp->link;
199  }
200  else
201  {
202  sp = sp->link = new_state(symbol);
203  found = 1;
204  }
205  }
206  }
207  }
208  else
209  {
210  state_set[key] = sp = new_state(symbol);
211  }
212 
213  return (sp->number);
214 }
215 
216 
217 
219 {
220  register int i;
221  register short *start_derives;
222  register core *p;
223 
224  start_derives = derives[start_symbol];
225  for (i = 0; start_derives[i] >= 0; ++i)
226  continue;
227 
228  p = (core *) MALLOC(sizeof(core) + i*sizeof(short));
229  if (p == 0) no_space();
230 
231  p->next = 0;
232  p->link = 0;
233  p->number = 0;
234  p->accessing_symbol = 0;
235  p->nitems = i;
236 
237  for (i = 0; start_derives[i] >= 0; ++i)
238  p->items[i] = rrhs[start_derives[i]];
239 
240  first_state = last_state = this_state = p;
241  nstates = 1;
242 }
243 
244 
246 {
247  register int i;
248  register int shiftcount;
249  register short *isp;
250  register short *ksp;
251  register int symbol;
252 
253  for (i = 0; i < nsyms; i++)
254  kernel_end[i] = 0;
255 
256  shiftcount = 0;
257  isp = itemset;
258  while (isp < itemsetend)
259  {
260  i = *isp++;
261  symbol = ritem[i];
262  if (symbol > 0)
263  {
264  ksp = kernel_end[symbol];
265  if (!ksp)
266  {
267  shift_symbol[shiftcount++] = symbol;
268  ksp = kernel_base[symbol];
269  }
270 
271  *ksp++ = i + 1;
272  kernel_end[symbol] = ksp;
273  }
274  }
275 
276  nshifts = shiftcount;
277 }
278 
279 
280 
281 core *
282 new_state(symbol)
283 int symbol;
284 {
285  register int n;
286  register core *p;
287  register short *isp1;
288  register short *isp2;
289  register short *iend;
290 
291 #ifdef TRACE
292  fprintf(stderr, "Entering new_state(%d)\n", symbol);
293 #endif
294 
295  if (nstates >= MAXSHORT)
296  fatal("too many states");
297 
298  isp1 = kernel_base[symbol];
299  iend = kernel_end[symbol];
300  n = iend - isp1;
301 
302  p = (core *) allocate((unsigned) (sizeof(core) + (n - 1) * sizeof(short)));
303  p->accessing_symbol = symbol;
304  p->number = nstates;
305  p->nitems = n;
306 
307  isp2 = p->items;
308  while (isp1 < iend)
309  *isp2++ = *isp1++;
310 
311  last_state->next = p;
312  last_state = p;
313 
314  nstates++;
315 
316  return (p);
317 }
318 
319 
320 /* show_cores is used for debugging */
321 
323 {
324  core *p;
325  int i, j, k, n;
326  int itemno;
327 
328  k = 0;
329  for (p = first_state; p; ++k, p = p->next)
330  {
331  if (k) printf("\n");
332  printf("state %d, number = %d, accessing symbol = %s\n",
333  k, p->number, symbol_name[p->accessing_symbol]);
334  n = p->nitems;
335  for (i = 0; i < n; ++i)
336  {
337  itemno = p->items[i];
338  printf("%4d ", itemno);
339  j = itemno;
340  while (ritem[j] >= 0) ++j;
341  printf("%s :", symbol_name[rlhs[-ritem[j]]]);
342  j = rrhs[-ritem[j]];
343  while (j < itemno)
344  printf(" %s", symbol_name[ritem[j++]]);
345  printf(" .");
346  while (ritem[j] >= 0)
347  printf(" %s", symbol_name[ritem[j++]]);
348  printf("\n");
349  fflush(stdout);
350  }
351  }
352 }
353 
354 
355 /* show_ritems is used for debugging */
356 
358 {
359  int i;
360 
361  for (i = 0; i < nitems; ++i)
362  printf("ritem[%d] = %d\n", i, ritem[i]);
363 }
364 
365 
366 /* show_rrhs is used for debugging */
368 {
369  int i;
370 
371  for (i = 0; i < nrules; ++i)
372  printf("rrhs[%d] = %d\n", i, rrhs[i]);
373 }
374 
375 
376 /* show_shifts is used for debugging */
377 
379 {
380  shifts *p;
381  int i, j, k;
382 
383  k = 0;
384  for (p = first_shift; p; ++k, p = p->next)
385  {
386  if (k) printf("\n");
387  printf("shift %d, number = %d, nshifts = %d\n", k, p->number,
388  p->nshifts);
389  j = p->nshifts;
390  for (i = 0; i < j; ++i)
391  printf("\t%d\n", p->shift[i]);
392  }
393 }
394 
395 
397 {
398  register shifts *p;
399  register short *sp1;
400  register short *sp2;
401  register short *send;
402 
403  p = (shifts *) allocate((unsigned) (sizeof(shifts) +
404  (nshifts - 1) * sizeof(short)));
405 
406  p->number = this_state->number;
407  p->nshifts = nshifts;
408 
409  sp1 = shiftset;
410  sp2 = p->shift;
411  send = shiftset + nshifts;
412 
413  while (sp1 < send)
414  *sp2++ = *sp1++;
415 
416  if (last_shift)
417  {
418  last_shift->next = p;
419  last_shift = p;
420  }
421  else
422  {
423  first_shift = p;
424  last_shift = p;
425  }
426 }
427 
428 
429 
431 {
432  register short *isp;
433  register short *rp1;
434  register short *rp2;
435  register int item;
436  register int count;
437  register reductions *p;
438  register short *rend;
439 
440  count = 0;
441  for (isp = itemset; isp < itemsetend; isp++)
442  {
443  item = ritem[*isp];
444  if (item < 0)
445  {
446  redset[count++] = -item;
447  }
448  }
449 
450  if (count)
451  {
452  p = (reductions *) allocate((unsigned) (sizeof(reductions) +
453  (count - 1) * sizeof(short)));
454 
455  p->number = this_state->number;
456  p->nreds = count;
457 
458  rp1 = redset;
459  rp2 = p->rules;
460  rend = rp1 + count;
461 
462  while (rp1 < rend)
463  *rp2++ = *rp1++;
464 
465  if (last_reduction)
466  {
467  last_reduction->next = p;
468  last_reduction = p;
469  }
470  else
471  {
472  first_reduction = p;
473  last_reduction = p;
474  }
475  }
476 }
477 
478 
480 {
481  register int i, k;
482  register int lhs;
483  register short *rules;
484 
485  derives = NEW2(nsyms, short *);
486  rules = NEW2(nvars + nrules, short);
487 
488  k = 0;
489  for (lhs = start_symbol; lhs < nsyms; lhs++)
490  {
491  derives[lhs] = rules + k;
492  for (i = 0; i < nrules; i++)
493  {
494  if (rlhs[i] == lhs)
495  {
496  rules[k] = i;
497  k++;
498  }
499  }
500  rules[k] = -1;
501  k++;
502  }
503 
504 #ifdef DEBUG
505  print_derives();
506 #endif
507 }
508 
510 {
512  FREE(derives);
513 }
514 
515 #ifdef DEBUG
516 print_derives()
517 {
518  register int i;
519  register short *sp;
520 
521  printf("\nDERIVES\n\n");
522 
523  for (i = start_symbol; i < nsyms; i++)
524  {
525  printf("%s derives ", symbol_name[i]);
526  for (sp = derives[i]; *sp >= 0; sp++)
527  {
528  printf(" %d", *sp);
529  }
530  putchar('\n');
531  }
532 
533  putchar('\n');
534 }
535 #endif
536 
537 
539 {
540  register int i, j;
541  register int empty;
542  int done;
543 
544  nullable = MALLOC(nsyms);
545  if (nullable == 0) no_space();
546 
547  for (i = 0; i < nsyms; ++i)
548  nullable[i] = 0;
549 
550  done = 0;
551  while (!done)
552  {
553  done = 1;
554  for (i = 1; i < nitems; i++)
555  {
556  empty = 1;
557  while ((j = ritem[i]) >= 0)
558  {
559  if (!nullable[j])
560  empty = 0;
561  ++i;
562  }
563  if (empty)
564  {
565  j = rlhs[-j];
566  if (!nullable[j])
567  {
568  nullable[j] = 1;
569  done = 0;
570  }
571  }
572  }
573  }
574 
575 #ifdef DEBUG
576  for (i = 0; i < nsyms; i++)
577  {
578  if (nullable[i])
579  printf("%s is nullable\n", symbol_name[i]);
580  else
581  printf("%s is not nullable\n", symbol_name[i]);
582  }
583 #endif
584 }
585 
586 
588 {
589  FREE(nullable);
590 }
591 
592 
594 {
595  set_derives();
596  set_nullable();
597  generate_states();
598 }
free_nullable()
Definition: lr0.c:587
show_shifts()
Definition: lr0.c:378
static short ** kernel_end
Definition: lr0.c:29
set_nullable()
Definition: lr0.c:538
finalize_closure()
Definition: closure.c:225
struct reductions * next
Definition: defs.h:157
short shift[1]
Definition: defs.h:148
short rules[1]
Definition: defs.h:160
#define MALLOC(n)
Definition: defs.h:103
new_itemsets()
Definition: lr0.c:245
allocate_storage()
Definition: lr0.c:75
core * new_state()
#define NEW2(n, t)
Definition: defs.h:105
shifts * first_shift
Definition: lr0.c:10
struct reductions reductions
Definition: defs.h:154
struct core * next
Definition: defs.h:131
Definition: defs.h:143
allocate_itemsets()
Definition: lr0.c:33
short * itemsetend
Definition: closure.c:4
short * rlhs
List of left-hand sides of all rules.
Definition: main.c:119
core * first_state
Definition: lr0.c:9
static short * kernel_items
Definition: lr0.c:30
closure(short *nucleus, int n)
Definition: closure.c:155
struct shifts shifts
Definition: defs.h:142
reductions * first_reduction
Definition: lr0.c:11
int nitems
Definition: main.c:40
free_storage()
Definition: lr0.c:113
short * itemset
Definition: closure.c:3
initialize_states()
Definition: lr0.c:218
done(int k)
Shutdown function.
Definition: main.c:156
static short * redset
Definition: lr0.c:25
show_cores()
Definition: lr0.c:322
static reductions * last_reduction
Definition: lr0.c:20
lr0()
Definition: lr0.c:593
struct shifts * next
Definition: defs.h:145
set_derives()
Definition: lr0.c:479
#define WORDSIZE(n)
Definition: defs.h:26
static core * this_state
Definition: lr0.c:17
unsigned * ruleset
Bitset of closure items for the current state.
Definition: closure.c:13
short number
Definition: defs.h:158
int nrules
The number of rules in the grammar.
Definition: main.c:45
short items[1]
Definition: defs.h:136
#define MAXSHORT
Definition: defs.h:22
no_space()
Definition: error.c:27
short nshifts
Definition: defs.h:147
static short * shift_symbol
Definition: lr0.c:23
char * nullable
Definition: main.c:141
set_first_derives()
Populates first_derives, the matrix of closure productions.
Definition: closure.c:100
Definition: defs.h:129
int nstates
Definition: lr0.c:8
int nvars
The number of variables (non-terminals) in the grammar.
Definition: main.c:74
show_rrhs()
Definition: lr0.c:367
char * allocate()
int nsyms
The number of symbols (terminals + non-terminals) in the grammar.
Definition: main.c:55
short * rrhs
List of right-hand sides of all rules.
Definition: main.c:126
struct core * link
Definition: defs.h:132
#define FREE(x)
Definition: defs.h:102
short * ritem
Representation of all productions (and items)
Definition: main.c:112
save_reductions()
Definition: lr0.c:430
short ** derives
List of rules that derive each non-terminal.
Definition: main.c:140
show_ritems()
Definition: lr0.c:357
short nitems
Definition: defs.h:135
int start_symbol
Index of the starting symbol of the grammar.
Definition: main.c:82
struct core core
Definition: defs.h:128
short nreds
Definition: defs.h:159
static short * shiftset
Definition: lr0.c:26
char ** symbol_name
Array of symbol names.
Definition: main.c:90
free_derives()
Definition: lr0.c:509
short accessing_symbol
Definition: defs.h:134
static short ** kernel_base
Definition: lr0.c:28
fatal(char *msg)
Definition: error.c:19
static core ** state_set
Definition: lr0.c:16
int get_state()
append_states()
Definition: lr0.c:84
static shifts * last_shift
Definition: lr0.c:19
static core * last_state
Definition: lr0.c:18
short number
Definition: defs.h:146
save_shifts()
Definition: lr0.c:396
short number
Definition: defs.h:133
static int nshifts
Definition: lr0.c:22
generate_states()
Definition: lr0.c:126