25 |
tokens they accept. */ |
tokens they accept. */ |
26 |
|
|
27 |
#include "system.h" |
#include "system.h" |
28 |
#include "bitset.h" |
|
29 |
#include "bitsetv.h" |
#include <bitset.h> |
30 |
#include "relation.h" |
#include <bitsetv.h> |
31 |
#include "quotearg.h" |
#include <quotearg.h> |
32 |
#include "symtab.h" |
|
|
#include "gram.h" |
|
|
#include "reader.h" |
|
33 |
#include "LR0.h" |
#include "LR0.h" |
34 |
#include "complain.h" |
#include "complain.h" |
|
#include "lalr.h" |
|
|
#include "nullable.h" |
|
35 |
#include "derives.h" |
#include "derives.h" |
36 |
#include "getargs.h" |
#include "getargs.h" |
37 |
|
#include "gram.h" |
38 |
|
#include "lalr.h" |
39 |
|
#include "nullable.h" |
40 |
|
#include "reader.h" |
41 |
|
#include "relation.h" |
42 |
|
#include "symtab.h" |
43 |
|
|
44 |
goto_number_t *goto_map = NULL; |
goto_number *goto_map = NULL; |
45 |
static goto_number_t ngotos = 0; |
static goto_number ngotos = 0; |
46 |
state_number_t *from_state = NULL; |
state_number *from_state = NULL; |
47 |
state_number_t *to_state = NULL; |
state_number *to_state = NULL; |
48 |
|
|
49 |
/* Linked list of goto numbers. */ |
/* Linked list of goto numbers. */ |
50 |
typedef struct goto_list_s |
typedef struct goto_list |
51 |
{ |
{ |
52 |
struct goto_list_s *next; |
struct goto_list *next; |
53 |
goto_number_t value; |
goto_number value; |
54 |
} goto_list_t; |
} goto_list; |
55 |
|
|
56 |
|
|
57 |
/* LA is a LR by NTOKENS matrix of bits. LA[l, i] is 1 if the rule |
/* LA is a LR by NTOKENS matrix of bits. LA[l, i] is 1 if the rule |
67 |
comment is hardly needed. <grin>. */ |
comment is hardly needed. <grin>. */ |
68 |
static bitsetv F = NULL; |
static bitsetv F = NULL; |
69 |
|
|
70 |
static goto_number_t **includes; |
static goto_number **includes; |
71 |
static goto_list_t **lookback; |
static goto_list **lookback; |
72 |
|
|
73 |
|
|
74 |
|
|
76 |
static void |
static void |
77 |
set_goto_map (void) |
set_goto_map (void) |
78 |
{ |
{ |
79 |
state_number_t state; |
state_number s; |
80 |
goto_number_t *temp_map; |
goto_number *temp_map; |
81 |
|
|
82 |
goto_map = XCALLOC (goto_number_t, nvars + 1) - ntokens; |
goto_map = XCALLOC (goto_number, nvars + 1) - ntokens; |
83 |
temp_map = XCALLOC (goto_number_t, nvars + 1) - ntokens; |
temp_map = XCALLOC (goto_number, nvars + 1) - ntokens; |
84 |
|
|
85 |
ngotos = 0; |
ngotos = 0; |
86 |
for (state = 0; state < nstates; ++state) |
for (s = 0; s < nstates; ++s) |
87 |
{ |
{ |
88 |
transitions_t *sp = states[state]->transitions; |
transitions *sp = states[s]->transitions; |
89 |
int i; |
int i; |
90 |
for (i = sp->num - 1; i >= 0 && TRANSITION_IS_GOTO (sp, i); --i) |
for (i = sp->num - 1; i >= 0 && TRANSITION_IS_GOTO (sp, i); --i) |
91 |
{ |
{ |
92 |
if (ngotos >= GOTO_NUMBER_MAX) |
if (ngotos >= GOTO_NUMBER_MAXIMUM) |
93 |
abort (); |
abort (); |
94 |
ngotos++; |
ngotos++; |
95 |
goto_map[TRANSITION_SYMBOL (sp, i)]++; |
goto_map[TRANSITION_SYMBOL (sp, i)]++; |
112 |
temp_map[nsyms] = ngotos; |
temp_map[nsyms] = ngotos; |
113 |
} |
} |
114 |
|
|
115 |
from_state = XCALLOC (state_number_t, ngotos); |
from_state = XCALLOC (state_number, ngotos); |
116 |
to_state = XCALLOC (state_number_t, ngotos); |
to_state = XCALLOC (state_number, ngotos); |
117 |
|
|
118 |
for (state = 0; state < nstates; ++state) |
for (s = 0; s < nstates; ++s) |
119 |
{ |
{ |
120 |
transitions_t *sp = states[state]->transitions; |
transitions *sp = states[s]->transitions; |
121 |
int i; |
int i; |
122 |
for (i = sp->num - 1; i >= 0 && TRANSITION_IS_GOTO (sp, i); --i) |
for (i = sp->num - 1; i >= 0 && TRANSITION_IS_GOTO (sp, i); --i) |
123 |
{ |
{ |
124 |
int k = temp_map[TRANSITION_SYMBOL (sp, i)]++; |
int k = temp_map[TRANSITION_SYMBOL (sp, i)]++; |
125 |
from_state[k] = state; |
from_state[k] = s; |
126 |
to_state[k] = sp->states[i]->number; |
to_state[k] = sp->states[i]->number; |
127 |
} |
} |
128 |
} |
} |
137 |
`----------------------------------------------------------*/ |
`----------------------------------------------------------*/ |
138 |
|
|
139 |
static int |
static int |
140 |
map_goto (state_number_t state, symbol_number_t symbol) |
map_goto (state_number s0, symbol_number sym) |
141 |
{ |
{ |
142 |
int high; |
int high; |
143 |
int low; |
int low; |
144 |
int middle; |
int middle; |
145 |
state_number_t s; |
state_number s; |
146 |
|
|
147 |
low = goto_map[symbol]; |
low = goto_map[sym]; |
148 |
high = goto_map[symbol + 1] - 1; |
high = goto_map[sym + 1] - 1; |
149 |
|
|
150 |
for (;;) |
for (;;) |
151 |
{ |
{ |
153 |
abort (); |
abort (); |
154 |
middle = (low + high) / 2; |
middle = (low + high) / 2; |
155 |
s = from_state[middle]; |
s = from_state[middle]; |
156 |
if (s == state) |
if (s == s0) |
157 |
return middle; |
return middle; |
158 |
else if (s < state) |
else if (s < s0) |
159 |
low = middle + 1; |
low = middle + 1; |
160 |
else |
else |
161 |
high = middle - 1; |
high = middle - 1; |
166 |
static void |
static void |
167 |
initialize_F (void) |
initialize_F (void) |
168 |
{ |
{ |
169 |
goto_number_t **reads = XCALLOC (goto_number_t *, ngotos); |
goto_number **reads = XCALLOC (goto_number *, ngotos); |
170 |
goto_number_t *edge = XCALLOC (goto_number_t, ngotos + 1); |
goto_number *edge = XCALLOC (goto_number, ngotos + 1); |
171 |
int nedges = 0; |
int nedges = 0; |
172 |
|
|
173 |
int i; |
int i; |
176 |
|
|
177 |
for (i = 0; i < ngotos; i++) |
for (i = 0; i < ngotos; i++) |
178 |
{ |
{ |
179 |
state_number_t stateno = to_state[i]; |
state_number stateno = to_state[i]; |
180 |
transitions_t *sp = states[stateno]->transitions; |
transitions *sp = states[stateno]->transitions; |
181 |
|
|
182 |
int j; |
int j; |
183 |
FOR_EACH_SHIFT (sp, j) |
FOR_EACH_SHIFT (sp, j) |
185 |
|
|
186 |
for (; j < sp->num; j++) |
for (; j < sp->num; j++) |
187 |
{ |
{ |
188 |
symbol_number_t symbol = TRANSITION_SYMBOL (sp, j); |
symbol_number sym = TRANSITION_SYMBOL (sp, j); |
189 |
if (nullable[symbol]) |
if (nullable[sym]) |
190 |
edge[nedges++] = map_goto (stateno, symbol); |
edge[nedges++] = map_goto (stateno, sym); |
191 |
} |
} |
192 |
|
|
193 |
if (nedges) |
if (nedges) |
194 |
{ |
{ |
195 |
reads[i] = XCALLOC (goto_number_t, nedges + 1); |
reads[i] = XCALLOC (goto_number, nedges + 1); |
196 |
memcpy (reads[i], edge, nedges * sizeof (edge[0])); |
memcpy (reads[i], edge, nedges * sizeof (edge[0])); |
197 |
reads[i][nedges] = -1; |
reads[i][nedges] = -1; |
198 |
nedges = 0; |
nedges = 0; |
210 |
|
|
211 |
|
|
212 |
static void |
static void |
213 |
add_lookback_edge (state_t *state, rule_t *rule, int gotono) |
add_lookback_edge (state *s, rule *r, int gotono) |
214 |
{ |
{ |
215 |
int r = state_reduction_find (state, rule); |
int ri = state_reduction_find (s, r); |
216 |
goto_list_t *sp = XCALLOC (goto_list_t, 1); |
goto_list *sp = XCALLOC (goto_list, 1); |
217 |
sp->next = lookback[(state->reductions->lookaheads - LA) + r]; |
sp->next = lookback[(s->reductions->lookaheads - LA) + ri]; |
218 |
sp->value = gotono; |
sp->value = gotono; |
219 |
lookback[(state->reductions->lookaheads - LA) + r] = sp; |
lookback[(s->reductions->lookaheads - LA) + ri] = sp; |
220 |
} |
} |
221 |
|
|
222 |
|
|
224 |
static void |
static void |
225 |
build_relations (void) |
build_relations (void) |
226 |
{ |
{ |
227 |
goto_number_t *edge = XCALLOC (goto_number_t, ngotos + 1); |
goto_number *edge = XCALLOC (goto_number, ngotos + 1); |
228 |
state_number_t *states1 = XCALLOC (state_number_t, ritem_longest_rhs () + 1); |
state_number *states1 = XCALLOC (state_number, ritem_longest_rhs () + 1); |
229 |
int i; |
int i; |
230 |
|
|
231 |
includes = XCALLOC (goto_number_t *, ngotos); |
includes = XCALLOC (goto_number *, ngotos); |
232 |
|
|
233 |
for (i = 0; i < ngotos; i++) |
for (i = 0; i < ngotos; i++) |
234 |
{ |
{ |
235 |
int nedges = 0; |
int nedges = 0; |
236 |
symbol_number_t symbol1 = states[to_state[i]]->accessing_symbol; |
symbol_number symbol1 = states[to_state[i]]->accessing_symbol; |
237 |
rule_t **rulep; |
rule **rulep; |
238 |
|
|
239 |
for (rulep = derives[symbol1]; *rulep; rulep++) |
for (rulep = derives[symbol1]; *rulep; rulep++) |
240 |
{ |
{ |
241 |
int done; |
int done; |
242 |
int length = 1; |
int length = 1; |
243 |
item_number_t *rp; |
item_number *rp; |
244 |
state_t *state = states[from_state[i]]; |
state *s = states[from_state[i]]; |
245 |
states1[0] = state->number; |
states1[0] = s->number; |
246 |
|
|
247 |
for (rp = (*rulep)->rhs; *rp >= 0; rp++) |
for (rp = (*rulep)->rhs; *rp >= 0; rp++) |
248 |
{ |
{ |
249 |
state = transitions_to (state->transitions, |
s = transitions_to (s->transitions, |
250 |
item_number_as_symbol_number (*rp)); |
item_number_as_symbol_number (*rp)); |
251 |
states1[length++] = state->number; |
states1[length++] = s->number; |
252 |
} |
} |
253 |
|
|
254 |
if (!state->consistent) |
if (!s->consistent) |
255 |
add_lookback_edge (state, *rulep, i); |
add_lookback_edge (s, *rulep, i); |
256 |
|
|
257 |
length--; |
length--; |
258 |
done = 0; |
done = 0; |
263 |
/* JF added rp>=ritem && I hope to god its right! */ |
/* JF added rp>=ritem && I hope to god its right! */ |
264 |
if (rp >= ritem && ISVAR (*rp)) |
if (rp >= ritem && ISVAR (*rp)) |
265 |
{ |
{ |
266 |
/* Downcasting from item_number_t to symbol_number_t. */ |
/* Downcasting from item_number to symbol_number. */ |
267 |
edge[nedges++] = map_goto (states1[--length], |
edge[nedges++] = map_goto (states1[--length], |
268 |
item_number_as_symbol_number (*rp)); |
item_number_as_symbol_number (*rp)); |
269 |
if (nullable[*rp]) |
if (nullable[*rp]) |
275 |
if (nedges) |
if (nedges) |
276 |
{ |
{ |
277 |
int j; |
int j; |
278 |
includes[i] = XCALLOC (goto_number_t, nedges + 1); |
includes[i] = XCALLOC (goto_number, nedges + 1); |
279 |
for (j = 0; j < nedges; j++) |
for (j = 0; j < nedges; j++) |
280 |
includes[i][j] = edge[j]; |
includes[i][j] = edge[j]; |
281 |
includes[i][nedges] = -1; |
includes[i][nedges] = -1; |
308 |
compute_lookaheads (void) |
compute_lookaheads (void) |
309 |
{ |
{ |
310 |
size_t i; |
size_t i; |
311 |
goto_list_t *sp; |
goto_list *sp; |
312 |
|
|
313 |
for (i = 0; i < nLA; i++) |
for (i = 0; i < nLA; i++) |
314 |
for (sp = lookback[i]; sp; sp = sp->next) |
for (sp = lookback[i]; sp; sp = sp->next) |
316 |
|
|
317 |
/* Free LOOKBACK. */ |
/* Free LOOKBACK. */ |
318 |
for (i = 0; i < nLA; i++) |
for (i = 0; i < nLA; i++) |
319 |
LIST_FREE (goto_list_t, lookback[i]); |
LIST_FREE (goto_list, lookback[i]); |
320 |
|
|
321 |
XFREE (lookback); |
XFREE (lookback); |
322 |
bitsetv_free (F); |
bitsetv_free (F); |
323 |
} |
} |
324 |
|
|
325 |
|
|
326 |
/*---------------------------------------------------------------. |
/*-----------------------------------------------------------. |
327 |
| Count the number of lookaheads required for STATE (NLOOKAHEADS | |
| Count the number of lookaheads required for S (NLOOKAHEADS | |
328 |
| member). | |
| member). | |
329 |
`---------------------------------------------------------------*/ |
`-----------------------------------------------------------*/ |
330 |
|
|
331 |
static int |
static int |
332 |
state_lookaheads_count (state_t *state) |
state_lookaheads_count (state *s) |
333 |
{ |
{ |
334 |
int k; |
int k; |
335 |
int nlookaheads = 0; |
int nlookaheads = 0; |
336 |
reductions_t *rp = state->reductions; |
reductions *rp = s->reductions; |
337 |
transitions_t *sp = state->transitions; |
transitions *sp = s->transitions; |
338 |
|
|
339 |
/* We need a lookahead either to distinguish different |
/* We need a lookahead either to distinguish different |
340 |
reductions (i.e., there are two or more), or to distinguish a |
reductions (i.e., there are two or more), or to distinguish a |
345 |
!TRANSITION_IS_DISABLED (sp, 0) && TRANSITION_IS_SHIFT (sp, 0))) |
!TRANSITION_IS_DISABLED (sp, 0) && TRANSITION_IS_SHIFT (sp, 0))) |
346 |
nlookaheads += rp->num; |
nlookaheads += rp->num; |
347 |
else |
else |
348 |
state->consistent = 1; |
s->consistent = 1; |
349 |
|
|
350 |
for (k = 0; k < sp->num; k++) |
for (k = 0; k < sp->num; k++) |
351 |
if (!TRANSITION_IS_DISABLED (sp, k) && TRANSITION_IS_ERROR (sp, k)) |
if (!TRANSITION_IS_DISABLED (sp, k) && TRANSITION_IS_ERROR (sp, k)) |
352 |
{ |
{ |
353 |
state->consistent = 0; |
s->consistent = 0; |
354 |
break; |
break; |
355 |
} |
} |
356 |
|
|
365 |
static void |
static void |
366 |
initialize_LA (void) |
initialize_LA (void) |
367 |
{ |
{ |
368 |
state_number_t i; |
state_number i; |
369 |
bitsetv pLA; |
bitsetv pLA; |
370 |
|
|
371 |
/* Compute the total number of reductions requiring a lookahead. */ |
/* Compute the total number of reductions requiring a lookahead. */ |
377 |
nLA = 1; |
nLA = 1; |
378 |
|
|
379 |
pLA = LA = bitsetv_create (nLA, ntokens, BITSET_FIXED); |
pLA = LA = bitsetv_create (nLA, ntokens, BITSET_FIXED); |
380 |
lookback = XCALLOC (goto_list_t *, nLA); |
lookback = XCALLOC (goto_list *, nLA); |
381 |
|
|
382 |
/* Initialize the members LOOKAHEADS for each state which reductions |
/* Initialize the members LOOKAHEADS for each state which reductions |
383 |
require lookaheads. */ |
require lookaheads. */ |
400 |
static void |
static void |
401 |
lookaheads_print (FILE *out) |
lookaheads_print (FILE *out) |
402 |
{ |
{ |
403 |
state_number_t i; |
state_number i; |
404 |
int j, k; |
int j, k; |
405 |
fprintf (out, "Lookaheads: BEGIN\n"); |
fprintf (out, "Lookaheads: BEGIN\n"); |
406 |
for (i = 0; i < nstates; ++i) |
for (i = 0; i < nstates; ++i) |
407 |
{ |
{ |
408 |
reductions_t *reds = states[i]->reductions; |
reductions *reds = states[i]->reductions; |
409 |
bitset_iterator iter; |
bitset_iterator iter; |
410 |
int nlookaheads = 0; |
int nlookaheads = 0; |
411 |
|
|
447 |
void |
void |
448 |
lalr_free (void) |
lalr_free (void) |
449 |
{ |
{ |
450 |
state_number_t s; |
state_number s; |
451 |
for (s = 0; s < nstates; ++s) |
for (s = 0; s < nstates; ++s) |
452 |
states[s]->reductions->lookaheads = NULL; |
states[s]->reductions->lookaheads = NULL; |
453 |
bitsetv_free (LA); |
bitsetv_free (LA); |