This is Unofficial EPICS BASE Doxygen Site
lalr.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 #include "defs.h"
10 
11 typedef
12  struct shorts
13  {
14  struct shorts *next;
15  short value;
16  }
17  shorts;
18 
20 short *lookaheads;
21 short *LAruleno;
22 unsigned *LA;
27 short *goto_map;
28 short *from_state;
29 short *to_state;
30 
31 static void set_state_table(void);
32 static void set_accessing_symbol(void);
33 static void set_shift_table(void);
34 static void set_reduction_table(void);
35 static void set_maxrhs(void);
36 static void initialize_LA(void);
37 static void set_goto_map(void);
38 static void initialize_F(void);
39 static void build_relations(void);
40 static void add_lookback_edge(int stateno, int ruleno, int gotono);
41 static short **transpose(short int **R, int n);
42 static void compute_FOLLOWS(void);
43 static void compute_lookaheads(void);
44 static void digraph(short **relation);
45 static void traverse(int i);
46 
47 static int infinity;
48 static int maxrhs;
49 static int ngotos;
50 static unsigned *F;
51 static short **includes;
52 static shorts **lookback;
53 static short **R;
54 static short *INDEX;
55 static short *VERTICES;
56 static int top;
57 
58 
59 void
60 lalr(void)
61 {
63 
64  set_state_table();
65  set_accessing_symbol();
66  set_shift_table();
67  set_reduction_table();
68  set_maxrhs();
69  initialize_LA();
70  set_goto_map();
71  initialize_F();
72  build_relations();
73  compute_FOLLOWS();
74  compute_lookaheads();
75 }
76 
77 
78 
79 static void
80 set_state_table(void)
81 {
82  core *sp;
83 
84  state_table = NEW2(nstates, core *);
85  for (sp = first_state; sp; sp = sp->next)
86  state_table[sp->number] = sp;
87 }
88 
89 
90 
91 static void
92 set_accessing_symbol(void)
93 {
94  core *sp;
95 
96  accessing_symbol = NEW2(nstates, short);
97  for (sp = first_state; sp; sp = sp->next)
99 }
100 
101 
102 
103 static void
104 set_shift_table(void)
105 {
106  shifts *sp;
107 
108  shift_table = NEW2(nstates, shifts *);
109  for (sp = first_shift; sp; sp = sp->next)
110  shift_table[sp->number] = sp;
111 }
112 
113 
114 
115 static void
116 set_reduction_table(void)
117 {
118  reductions *rp;
119 
120  reduction_table = NEW2(nstates, reductions *);
121  for (rp = first_reduction; rp; rp = rp->next)
122  reduction_table[rp->number] = rp;
123 }
124 
125 
126 
127 static void
128 set_maxrhs(void)
129 {
130  short *itemp;
131  short *item_end;
132  int length;
133  int max;
134 
135  length = 0;
136  max = 0;
137  item_end = ritem + nitems;
138  for (itemp = ritem; itemp < item_end; itemp++)
139  {
140  if (*itemp >= 0)
141  {
142  length++;
143  }
144  else
145  {
146  if (length > max) max = length;
147  length = 0;
148  }
149  }
150 
151  maxrhs = max;
152 }
153 
154 
155 
156 static void
157 initialize_LA(void)
158 {
159  int i, j, k;
160  reductions *rp;
161 
162  lookaheads = NEW2(nstates + 1, short);
163 
164  k = 0;
165  for (i = 0; i < nstates; i++)
166  {
167  lookaheads[i] = k;
168  rp = reduction_table[i];
169  if (rp)
170  k += rp->nreds;
171  }
172  lookaheads[nstates] = k;
173 
174  LA = NEW2(k * tokensetsize, unsigned);
175  LAruleno = NEW2(k, short);
176  lookback = NEW2(k, shorts *);
177 
178  k = 0;
179  for (i = 0; i < nstates; i++)
180  {
181  rp = reduction_table[i];
182  if (rp)
183  {
184  for (j = 0; j < rp->nreds; j++)
185  {
186  LAruleno[k] = rp->rules[j];
187  k++;
188  }
189  }
190  }
191 }
192 
193 
194 static void
195 set_goto_map(void)
196 {
197  shifts *sp;
198  int i;
199  int symbol;
200  int k;
201  short *temp_map;
202  int state2;
203  int state1;
204 
205  goto_map = NEW2(nvars + 1, short) - ntokens;
206  temp_map = NEW2(nvars + 1, short) - ntokens;
207 
208  ngotos = 0;
209  for (sp = first_shift; sp; sp = sp->next)
210  {
211  for (i = sp->nshifts - 1; i >= 0; i--)
212  {
213  symbol = accessing_symbol[sp->shift[i]];
214 
215  if (ISTOKEN(symbol)) break;
216 
217  if (ngotos == MAXSHORT)
218  fatal("too many gotos");
219 
220  ngotos++;
221  goto_map[symbol]++;
222  }
223  }
224 
225  k = 0;
226  for (i = ntokens; i < nsyms; i++)
227  {
228  temp_map[i] = k;
229  k += goto_map[i];
230  }
231 
232  for (i = ntokens; i < nsyms; i++)
233  goto_map[i] = temp_map[i];
234 
235  goto_map[nsyms] = ngotos;
236  temp_map[nsyms] = ngotos;
237 
238  from_state = NEW2(ngotos, short);
239  to_state = NEW2(ngotos, short);
240 
241  for (sp = first_shift; sp; sp = sp->next)
242  {
243  state1 = sp->number;
244  for (i = sp->nshifts - 1; i >= 0; i--)
245  {
246  state2 = sp->shift[i];
247  symbol = accessing_symbol[state2];
248 
249  if (ISTOKEN(symbol)) break;
250 
251  k = temp_map[symbol]++;
252  from_state[k] = state1;
253  to_state[k] = state2;
254  }
255  }
256 
257  FREE(temp_map + ntokens);
258 }
259 
260 
261 
262 /* Map_goto maps a state/symbol pair into its numeric representation. */
263 
264 int
265 map_goto(int state, int symbol)
266 {
267  int high;
268  int low;
269  int middle;
270  int s;
271 
272  low = goto_map[symbol];
273  high = goto_map[symbol + 1];
274 
275  for (;;)
276  {
277  assert(low <= high);
278  middle = (low + high) >> 1;
279  s = from_state[middle];
280  if (s == state)
281  return (middle);
282  else if (s < state)
283  low = middle + 1;
284  else
285  high = middle - 1;
286  }
287 }
288 
289 
290 
291 static void
292 initialize_F(void)
293 {
294  int i;
295  int j;
296  int k;
297  shifts *sp;
298  short *edge;
299  unsigned *rowp;
300  short *rp;
301  short **reads;
302  int nedges;
303  int stateno;
304  int symbol;
305  int nwords;
306 
307  nwords = ngotos * tokensetsize;
308  F = NEW2(nwords, unsigned);
309 
310  reads = NEW2(ngotos, short *);
311  edge = NEW2(ngotos + 1, short);
312  nedges = 0;
313 
314  rowp = F;
315  for (i = 0; i < ngotos; i++)
316  {
317  stateno = to_state[i];
318  sp = shift_table[stateno];
319 
320  if (sp)
321  {
322  k = sp->nshifts;
323 
324  for (j = 0; j < k; j++)
325  {
326  symbol = accessing_symbol[sp->shift[j]];
327  if (ISVAR(symbol))
328  break;
329  SETBIT(rowp, symbol);
330  }
331 
332  for (; j < k; j++)
333  {
334  symbol = accessing_symbol[sp->shift[j]];
335  if (nullable[symbol])
336  edge[nedges++] = map_goto(stateno, symbol);
337  }
338 
339  if (nedges)
340  {
341  reads[i] = rp = NEW2(nedges + 1, short);
342 
343  for (j = 0; j < nedges; j++)
344  rp[j] = edge[j];
345 
346  rp[nedges] = -1;
347  nedges = 0;
348  }
349  }
350 
351  rowp += tokensetsize;
352  }
353 
354  SETBIT(F, 0);
355  digraph(reads);
356 
357  for (i = 0; i < ngotos; i++)
358  {
359  if (reads[i])
360  FREE(reads[i]);
361  }
362 
363  FREE(reads);
364  FREE(edge);
365 }
366 
367 
368 
369 static void
370 build_relations(void)
371 {
372  int i;
373  int j;
374  int k;
375  short *rulep;
376  short *rp;
377  shifts *sp;
378  int length;
379  int nedges;
380  int done;
381  int state1;
382  int stateno;
383  int symbol1;
384  int symbol2;
385  short *shortp;
386  short *edge;
387  short *states;
388  short **new_includes;
389 
390  includes = NEW2(ngotos, short *);
391  edge = NEW2(ngotos + 1, short);
392  states = NEW2(maxrhs + 1, short);
393 
394  for (i = 0; i < ngotos; i++)
395  {
396  nedges = 0;
397  state1 = from_state[i];
398  symbol1 = accessing_symbol[to_state[i]];
399 
400  for (rulep = derives[symbol1]; *rulep >= 0; rulep++)
401  {
402  length = 1;
403  states[0] = state1;
404  stateno = state1;
405 
406  for (rp = ritem + rrhs[*rulep]; *rp >= 0; rp++)
407  {
408  symbol2 = *rp;
409  sp = shift_table[stateno];
410  k = sp->nshifts;
411 
412  for (j = 0; j < k; j++)
413  {
414  stateno = sp->shift[j];
415  if (accessing_symbol[stateno] == symbol2) break;
416  }
417 
418  states[length++] = stateno;
419  }
420 
421  add_lookback_edge(stateno, *rulep, i);
422 
423  length--;
424  done = 0;
425  while (!done)
426  {
427  done = 1;
428  rp--;
429  if (ISVAR(*rp))
430  {
431  stateno = states[--length];
432  edge[nedges++] = map_goto(stateno, *rp);
433  if (nullable[*rp] && length > 0) done = 0;
434  }
435  }
436  }
437 
438  if (nedges)
439  {
440  includes[i] = shortp = NEW2(nedges + 1, short);
441  for (j = 0; j < nedges; j++)
442  shortp[j] = edge[j];
443  shortp[nedges] = -1;
444  }
445  }
446 
447  new_includes = transpose(includes, ngotos);
448 
449  for (i = 0; i < ngotos; i++)
450  if (includes[i])
451  FREE(includes[i]);
452 
453  FREE(includes);
454 
455  includes = new_includes;
456 
457  FREE(edge);
458  FREE(states);
459 }
460 
461 
462 static void
463 add_lookback_edge(int stateno, int ruleno, int gotono)
464 {
465  int i, k;
466  int found;
467  shorts *sp;
468 
469  i = lookaheads[stateno];
470  k = lookaheads[stateno + 1];
471  found = 0;
472  while (!found && i < k)
473  {
474  if (LAruleno[i] == ruleno)
475  found = 1;
476  else
477  ++i;
478  }
479  assert(found);
480 
481  sp = NEW(shorts);
482  sp->next = lookback[i];
483  sp->value = gotono;
484  lookback[i] = sp;
485 }
486 
487 
488 
489 short **
490 transpose(short int **R, int n)
491 {
492  short **new_R;
493  short **temp_R;
494  short *nedges;
495  short *sp;
496  int i;
497  int k;
498 
499  nedges = NEW2(n, short);
500 
501  for (i = 0; i < n; i++)
502  {
503  sp = R[i];
504  if (sp)
505  {
506  while (*sp >= 0)
507  nedges[*sp++]++;
508  }
509  }
510 
511  new_R = NEW2(n, short *);
512  temp_R = NEW2(n, short *);
513 
514  for (i = 0; i < n; i++)
515  {
516  k = nedges[i];
517  if (k > 0)
518  {
519  sp = NEW2(k + 1, short);
520  new_R[i] = sp;
521  temp_R[i] = sp;
522  sp[k] = -1;
523  }
524  }
525 
526  FREE(nedges);
527 
528  for (i = 0; i < n; i++)
529  {
530  sp = R[i];
531  if (sp)
532  {
533  while (*sp >= 0)
534  *temp_R[*sp++]++ = i;
535  }
536  }
537 
538  FREE(temp_R);
539 
540  return (new_R);
541 }
542 
543 
544 
545 static void
546 compute_FOLLOWS(void)
547 {
548  digraph(includes);
549 }
550 
551 
552 static void
553 compute_lookaheads(void)
554 {
555  int i, n;
556  unsigned *fp1, *fp2, *fp3;
557  shorts *sp, *next;
558  unsigned *rowp;
559 
560  rowp = LA;
561  n = lookaheads[nstates];
562  for (i = 0; i < n; i++)
563  {
564  fp3 = rowp + tokensetsize;
565  for (sp = lookback[i]; sp; sp = sp->next)
566  {
567  fp1 = rowp;
568  fp2 = F + tokensetsize * sp->value;
569  while (fp1 < fp3)
570  *fp1++ |= *fp2++;
571  }
572  rowp = fp3;
573  }
574 
575  for (i = 0; i < n; i++)
576  for (sp = lookback[i]; sp; sp = next)
577  {
578  next = sp->next;
579  FREE(sp);
580  }
581 
582  FREE(lookback);
583  FREE(F);
584 }
585 
586 
587 static void
588 digraph(short **relation)
589 {
590  int i;
591 
592  infinity = ngotos + 2;
593  INDEX = NEW2(ngotos + 1, short);
594  VERTICES = NEW2(ngotos + 1, short);
595  top = 0;
596 
597  R = relation;
598 
599  for (i = 0; i < ngotos; i++)
600  INDEX[i] = 0;
601 
602  for (i = 0; i < ngotos; i++)
603  {
604  if (INDEX[i] == 0 && R[i])
605  traverse(i);
606  }
607 
608  FREE(INDEX);
609  FREE(VERTICES);
610 }
611 
612 
613 
614 static void
615 traverse(int i)
616 {
617  unsigned *fp1;
618  unsigned *fp2;
619  unsigned *fp3;
620  int j;
621  short *rp;
622 
623  int height;
624  unsigned *base;
625 
626  VERTICES[++top] = i;
627  INDEX[i] = height = top;
628 
629  base = F + i * tokensetsize;
630  fp3 = base + tokensetsize;
631 
632  rp = R[i];
633  if (rp)
634  {
635  while ((j = *rp++) >= 0)
636  {
637  if (INDEX[j] == 0)
638  traverse(j);
639 
640  if (INDEX[i] > INDEX[j])
641  INDEX[i] = INDEX[j];
642 
643  fp1 = base;
644  fp2 = F + j * tokensetsize;
645 
646  while (fp1 < fp3)
647  *fp1++ |= *fp2++;
648  }
649  }
650 
651  if (INDEX[i] == height)
652  {
653  for (;;)
654  {
655  j = VERTICES[top--];
656  INDEX[j] = infinity;
657 
658  if (i == j)
659  break;
660 
661  fp1 = base;
662  fp2 = F + j * tokensetsize;
663 
664  while (fp1 < fp3)
665  *fp2++ = *fp1++;
666  }
667  }
668 }
reductions ** reduction_table
Definition: lalr.c:26
void fatal(char *msg) NORETURN
Definition: error.c:15
short * LAruleno
Definition: lalr.c:21
#define max(x, y)
Definition: flexdef.h:81
core ** state_table
Definition: lalr.c:24
#define assert(exp)
Declare that a condition should be true.
Definition: epicsAssert.h:70
struct reductions * next
Definition: defs.h:165
short * to_state
Definition: lalr.c:29
short shift[1]
Definition: defs.h:156
short rules[1]
Definition: defs.h:168
int i
Definition: scan.c:967
#define NEW2(n, t)
Definition: defs.h:113
struct core * next
Definition: defs.h:139
Definition: defs.h:151
short * goto_map
Definition: lalr.c:27
core * first_state
Definition: lr0.c:17
short * accessing_symbol
Definition: lalr.c:23
int nstates
Definition: lr0.c:16
#define ISVAR(s)
Definition: defs.h:104
int nitems
Definition: antelope.c:55
int nsyms
Definition: antelope.c:57
struct shorts * next
Definition: lalr.c:14
struct shifts * next
Definition: defs.h:153
int nvars
Definition: antelope.c:59
int map_goto(int state, int symbol)
Definition: lalr.c:265
#define WORDSIZE(n)
Definition: defs.h:34
shifts * first_shift
Definition: lr0.c:18
char * nullable
Definition: antelope.c:73
short ** derives
Definition: antelope.c:72
short number
Definition: defs.h:166
reductions * first_reduction
Definition: lr0.c:19
#define MAXSHORT
Definition: defs.h:30
short nshifts
Definition: defs.h:155
short value
Definition: lalr.c:15
Definition: defs.h:137
short * ritem
Definition: antelope.c:67
short * from_state
Definition: lalr.c:28
Definition: lalr.c:11
#define ISTOKEN(s)
Definition: defs.h:103
int tokensetsize
Definition: lalr.c:19
#define FREE(x)
Definition: defs.h:110
short * rrhs
Definition: antelope.c:69
void done(int k)
Definition: antelope.c:77
#define SETBIT(r, n)
Definition: defs.h:36
short nreds
Definition: defs.h:167
int ntokens
Definition: antelope.c:58
int * base
Definition: flex.c:92
short accessing_symbol
Definition: defs.h:142
shifts ** shift_table
Definition: lalr.c:25
unsigned * LA
Definition: lalr.c:22
void lalr(void)
Definition: lalr.c:60
short * lookaheads
Definition: lalr.c:20
struct shorts shorts
short number
Definition: defs.h:154
#define NEW(t)
Definition: defs.h:112
short number
Definition: defs.h:141