This is Unofficial EPICS BASE Doxygen Site
mkpar.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 
13 int SRtotal;
14 int RRtotal;
15 short *SRconflicts;
16 short *RRconflicts;
17 short *defred;
18 short *rules_used;
19 short nunused;
21 
22 static int SRcount;
23 static int RRcount;
24 
25 
26 static action *parse_actions(int stateno);
27 static action *get_shifts(int stateno);
28 static action *add_reductions(int stateno, action *actions);
29 static action *add_reduce(action *actions, int ruleno, int symbol);
30 static void find_final_state(void);
31 static void unused_rules(void);
32 static void remove_conflicts(void);
33 static void total_conflicts(void);
34 static void defreds(void);
35 
36 void
38 {
39  int i;
40 
41  parser = NEW2(nstates, action *);
42  for (i = 0; i < nstates; i++)
43  parser[i] = parse_actions(i);
44 
45  find_final_state();
46  remove_conflicts();
47  unused_rules();
48  if (SRtotal + RRtotal > 0) total_conflicts();
49  defreds();
50 }
51 
52 
53 static action *
54 parse_actions(int stateno)
55 {
56  action *actions;
57 
58  actions = get_shifts(stateno);
59  actions = add_reductions(stateno, actions);
60  return (actions);
61 }
62 
63 
64 static action *
65 get_shifts(int stateno)
66 {
67  action *actions, *temp;
68  shifts *sp;
69  short *to_state;
70  int i, k;
71  int symbol;
72 
73  actions = 0;
74  sp = shift_table[stateno];
75  if (sp)
76  {
77  to_state = sp->shift;
78  for (i = sp->nshifts - 1; i >= 0; i--)
79  {
80  k = to_state[i];
81  symbol = accessing_symbol[k];
82  if (ISTOKEN(symbol))
83  {
84  temp = NEW(action);
85  temp->next = actions;
86  temp->symbol = symbol;
87  temp->number = k;
88  temp->prec = symbol_prec[symbol];
89  temp->action_code = SHIFT;
90  temp->assoc = symbol_assoc[symbol];
91  actions = temp;
92  }
93  }
94  }
95  return (actions);
96 }
97 
98 static action *
99 add_reductions(int stateno, action *actions)
100 {
101  int i, j, m, n;
102  int ruleno, tokensetsize;
103  unsigned *rowp;
104 
105  tokensetsize = WORDSIZE(ntokens);
106  m = lookaheads[stateno];
107  n = lookaheads[stateno + 1];
108  for (i = m; i < n; i++)
109  {
110  ruleno = LAruleno[i];
111  rowp = LA + i * tokensetsize;
112  for (j = ntokens - 1; j >= 0; j--)
113  {
114  if (BIT(rowp, j))
115  actions = add_reduce(actions, ruleno, j);
116  }
117  }
118  return (actions);
119 }
120 
121 
122 static action *
123 add_reduce(action *actions, int ruleno, int symbol)
124 {
125  action *temp, *prev, *next;
126 
127  prev = 0;
128  for (next = actions; next && next->symbol < symbol; next = next->next)
129  prev = next;
130 
131  while (next && next->symbol == symbol && next->action_code == SHIFT)
132  {
133  prev = next;
134  next = next->next;
135  }
136 
137  while (next && next->symbol == symbol &&
138  next->action_code == REDUCE && next->number < ruleno)
139  {
140  prev = next;
141  next = next->next;
142  }
143 
144  temp = NEW(action);
145  temp->next = next;
146  temp->symbol = symbol;
147  temp->number = ruleno;
148  temp->prec = rprec[ruleno];
149  temp->action_code = REDUCE;
150  temp->assoc = rassoc[ruleno];
151 
152  if (prev)
153  prev->next = temp;
154  else
155  actions = temp;
156 
157  return (actions);
158 }
159 
160 
161 static void
162 find_final_state(void)
163 {
164  int goal, i;
165  short *to_state;
166  shifts *p;
167 
168  p = shift_table[0];
169  to_state = p->shift;
170  goal = ritem[1];
171  for (i = p->nshifts - 1; i >= 0; --i)
172  {
173  final_state = to_state[i];
174  if (accessing_symbol[final_state] == goal) break;
175  }
176 }
177 
178 
179 static void
180 unused_rules(void)
181 {
182  int i;
183  action *p;
184 
185  rules_used = (short *) MALLOC(nrules*sizeof(short));
186  if (rules_used == 0) no_space();
187 
188  for (i = 0; i < nrules; ++i)
189  rules_used[i] = 0;
190 
191  for (i = 0; i < nstates; ++i)
192  {
193  for (p = parser[i]; p; p = p->next)
194  {
195  if (p->action_code == REDUCE && p->suppressed == 0)
196  rules_used[p->number] = 1;
197  }
198  }
199 
200  nunused = 0;
201  for (i = 3; i < nrules; ++i)
202  if (!rules_used[i]) ++nunused;
203 
204  if (nunused)
205  {
206  if (nunused == 1)
207  fprintf(stderr, "%s: 1 rule never reduced\n", myname);
208  else
209  fprintf(stderr, "%s: %d rules never reduced\n", myname, nunused);
210  }
211 }
212 
213 
214 static void
215 remove_conflicts(void)
216 {
217  int i;
218  int symbol;
219  action *p, *pref = NULL;
220 
221  SRtotal = 0;
222  RRtotal = 0;
223  SRconflicts = NEW2(nstates, short);
224  RRconflicts = NEW2(nstates, short);
225  for (i = 0; i < nstates; i++)
226  {
227  SRcount = 0;
228  RRcount = 0;
229  symbol = -1;
230  for (p = parser[i]; p; p = p->next)
231  {
232  if (p->symbol != symbol)
233  {
234  pref = p;
235  symbol = p->symbol;
236  }
237  else if (i == final_state && symbol == 0)
238  {
239  SRcount++;
240  p->suppressed = 1;
241  }
242  else if (pref && pref->action_code == SHIFT)
243  {
244  if (pref->prec > 0 && p->prec > 0)
245  {
246  if (pref->prec < p->prec)
247  {
248  pref->suppressed = 2;
249  pref = p;
250  }
251  else if (pref->prec > p->prec)
252  {
253  p->suppressed = 2;
254  }
255  else if (pref->assoc == LEFT)
256  {
257  pref->suppressed = 2;
258  pref = p;
259  }
260  else if (pref->assoc == RIGHT)
261  {
262  p->suppressed = 2;
263  }
264  else
265  {
266  pref->suppressed = 2;
267  p->suppressed = 2;
268  }
269  }
270  else
271  {
272  SRcount++;
273  p->suppressed = 1;
274  }
275  }
276  else
277  {
278  RRcount++;
279  p->suppressed = 1;
280  }
281  }
282  SRtotal += SRcount;
283  RRtotal += RRcount;
284  SRconflicts[i] = SRcount;
285  RRconflicts[i] = RRcount;
286  }
287 }
288 
289 
290 static void
291 total_conflicts(void)
292 {
293  fprintf(stderr, "%s: ", myname);
294  if (SRtotal == 1)
295  fprintf(stderr, "1 shift/reduce conflict");
296  else if (SRtotal > 1)
297  fprintf(stderr, "%d shift/reduce conflicts", SRtotal);
298 
299  if (SRtotal && RRtotal)
300  fprintf(stderr, ", ");
301 
302  if (RRtotal == 1)
303  fprintf(stderr, "1 reduce/reduce conflict");
304  else if (RRtotal > 1)
305  fprintf(stderr, "%d reduce/reduce conflicts", RRtotal);
306 
307  fprintf(stderr, ".\n");
308 }
309 
310 
311 static int
312 sole_reduction(int stateno)
313 {
314  int count, ruleno;
315  action *p;
316 
317  count = 0;
318  ruleno = 0;
319  for (p = parser[stateno]; p; p = p->next)
320  {
321  if (p->action_code == SHIFT && p->suppressed == 0)
322  return 0;
323  else if (p->action_code == REDUCE && p->suppressed == 0)
324  {
325  if (ruleno > 0 && p->number != ruleno)
326  return 0;
327  if (p->symbol != 1)
328  ++count;
329  ruleno = p->number;
330  }
331  }
332 
333  if (count == 0)
334  return 0;
335  return ruleno;
336 }
337 
338 
339 static void
340 defreds(void)
341 {
342  int i;
343 
344  defred = NEW2(nstates, short);
345  for (i = 0; i < nstates; i++)
346  defred[i] = sole_reduction(i);
347 }
348 
349 static void
350 free_action_row(action *p)
351 {
352  action *q;
353 
354  while (p)
355  {
356  q = p->next;
357  FREE(p);
358  p = q;
359  }
360 }
361 
362 void
364 {
365  int i;
366 
367  for (i = 0; i < nstates; i++)
368  free_action_row(parser[i]);
369 
370  FREE(parser);
371 }
372 
#define BIT(r, n)
Definition: defs.h:35
short number
Definition: defs.h:179
short * LAruleno
Definition: lalr.c:21
short shift[1]
Definition: defs.h:156
unsigned * LA
Definition: lalr.c:22
#define MALLOC(n)
Definition: defs.h:111
int i
Definition: scan.c:967
Definition: defs.h:175
short * accessing_symbol
Definition: lalr.c:23
short * RRconflicts
Definition: mkpar.c:16
#define NEW2(n, t)
Definition: defs.h:113
Definition: defs.h:151
short * lookaheads
Definition: lalr.c:20
char * rassoc
Definition: antelope.c:71
void free_parser(void)
Definition: mkpar.c:363
int SRtotal
Definition: mkpar.c:13
#define NULL
Definition: catime.c:38
int nstates
Definition: lr0.c:16
int nrules
Definition: antelope.c:56
short nunused
Definition: mkpar.c:19
shifts ** shift_table
Definition: lalr.c:25
short final_state
Definition: mkpar.c:20
short * to_state
Definition: lalr.c:29
struct shorts * next
Definition: lalr.c:14
char action_code
Definition: defs.h:181
action ** parser
Definition: mkpar.c:12
#define WORDSIZE(n)
Definition: defs.h:34
short * rules_used
Definition: mkpar.c:18
short * SRconflicts
Definition: mkpar.c:15
char * myname
Definition: antelope.c:30
short nshifts
Definition: defs.h:155
struct action * next
Definition: defs.h:177
short * ritem
Definition: antelope.c:67
short * symbol_prec
Definition: antelope.c:64
short symbol
Definition: defs.h:178
#define LEFT
Definition: defs.h:65
int RRtotal
Definition: mkpar.c:14
#define SHIFT
Definition: defs.h:90
short * defred
Definition: mkpar.c:17
#define ISTOKEN(s)
Definition: defs.h:103
int tokensetsize
Definition: lalr.c:19
#define RIGHT
Definition: defs.h:66
#define FREE(x)
Definition: defs.h:110
char assoc
Definition: defs.h:182
bucket * goal
Definition: reader.c:28
int ntokens
Definition: antelope.c:58
char * symbol_assoc
Definition: antelope.c:65
#define stderr
Definition: epicsStdio.h:32
short prec
Definition: defs.h:180
void no_space(void) NORETURN
Definition: error.c:23
short * rprec
Definition: antelope.c:70
void make_parser(void)
Definition: mkpar.c:37
#define REDUCE
Definition: defs.h:91
#define NEW(t)
Definition: defs.h:112
char suppressed
Definition: defs.h:183