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