]> git.saurik.com Git - bison.git/blame - src/lalr.c
Use unlocked I/O for a minor performance improvement on hosts like
[bison.git] / src / lalr.c
CommitLineData
5362cd5f
PE
1/* Compute look-ahead criteria for Bison.
2
8dd162d3 3 Copyright (C) 1984, 1986, 1989, 2000, 2001, 2002, 2003, 2004
b0299a2e 4 Free Software Foundation, Inc.
d0fb370f 5
340ef489 6 This file is part of Bison, the GNU Compiler Compiler.
d0fb370f 7
340ef489
AD
8 Bison is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
d0fb370f 12
340ef489
AD
13 Bison is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
d0fb370f 17
340ef489
AD
18 You should have received a copy of the GNU General Public License
19 along with Bison; see the file COPYING. If not, write to
0fb669f9
PE
20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
d0fb370f
RS
22
23
720d742f 24/* Compute how to make the finite state machine deterministic; find
8dd162d3 25 which rules need look-ahead in each state, and which look-ahead
340ef489 26 tokens they accept. */
d0fb370f 27
d0fb370f 28#include "system.h"
5dde5425
PE
29
30#include <bitset.h>
31#include <bitsetv.h>
32#include <quotearg.h>
33
b2ca4022 34#include "LR0.h"
a0f6b076 35#include "complain.h"
340ef489 36#include "derives.h"
f67d13aa 37#include "getargs.h"
5dde5425
PE
38#include "gram.h"
39#include "lalr.h"
40#include "nullable.h"
41#include "reader.h"
42#include "relation.h"
43#include "symtab.h"
d0fb370f 44
4cf44c00
PE
45goto_number *goto_map;
46static goto_number ngotos;
47state_number *from_state;
48state_number *to_state;
e68e0410
AD
49
50/* Linked list of goto numbers. */
5dde5425 51typedef struct goto_list
e68e0410 52{
5dde5425
PE
53 struct goto_list *next;
54 goto_number value;
55} goto_list;
e68e0410
AD
56
57
3325ddc4
AD
58/* LA is a LR by NTOKENS matrix of bits. LA[l, i] is 1 if the rule
59 LArule[l] is applicable in the appropriate state when the next
60 token is symbol i. If LA[l, i] and LA[l, j] are both 1 for i != j,
61 it is a conflict. */
62
63static bitsetv LA = NULL;
d200e455 64size_t nLA;
9703cc49 65
d0fb370f 66
fe961097 67/* And for the famous F variable, which name is so descriptive that a
ddcd5fdf 68 comment is hardly needed. <grin>. */
914feea9 69static bitsetv F = NULL;
ddcd5fdf 70
5dde5425
PE
71static goto_number **includes;
72static goto_list **lookback;
aa2aab3c
AD
73
74
720d742f 75
bb527fc2 76
4a120d45 77static void
d2729d44 78set_goto_map (void)
d0fb370f 79{
5dde5425
PE
80 state_number s;
81 goto_number *temp_map;
d0fb370f 82
da2a7671
PE
83 goto_map = xcalloc (nvars + 1, sizeof *goto_map);
84 temp_map = xnmalloc (nvars + 1, sizeof *temp_map);
d0fb370f
RS
85
86 ngotos = 0;
5dde5425 87 for (s = 0; s < nstates; ++s)
7215de24 88 {
5dde5425 89 transitions *sp = states[s]->transitions;
d57650a5 90 int i;
ccaf65bc 91 for (i = sp->num - 1; i >= 0 && TRANSITION_IS_GOTO (sp, i); --i)
7215de24 92 {
7215de24 93 ngotos++;
60e3ecc7
PE
94
95 /* Abort if (ngotos + 1) would overflow. */
96 if (ngotos == GOTO_NUMBER_MAXIMUM)
4cf44c00 97 abort ();
60e3ecc7 98
5362cd5f 99 goto_map[TRANSITION_SYMBOL (sp, i) - ntokens]++;
7215de24
AD
100 }
101 }
d0fb370f 102
d0b0fefa 103 {
60e3ecc7 104 goto_number k = 0;
d57650a5 105 int i;
d0b0fefa
AD
106 for (i = ntokens; i < nsyms; i++)
107 {
5362cd5f
PE
108 temp_map[i - ntokens] = k;
109 k += goto_map[i - ntokens];
d0b0fefa 110 }
d0fb370f 111
d0b0fefa 112 for (i = ntokens; i < nsyms; i++)
5362cd5f 113 goto_map[i - ntokens] = temp_map[i - ntokens];
d0fb370f 114
5362cd5f
PE
115 goto_map[nsyms - ntokens] = ngotos;
116 temp_map[nsyms - ntokens] = ngotos;
d0b0fefa 117 }
d0fb370f 118
da2a7671
PE
119 from_state = xcalloc (ngotos, sizeof *from_state);
120 to_state = xcalloc (ngotos, sizeof *to_state);
d0fb370f 121
5dde5425 122 for (s = 0; s < nstates; ++s)
d0fb370f 123 {
5dde5425 124 transitions *sp = states[s]->transitions;
d57650a5 125 int i;
ccaf65bc 126 for (i = sp->num - 1; i >= 0 && TRANSITION_IS_GOTO (sp, i); --i)
d0fb370f 127 {
60e3ecc7 128 goto_number k = temp_map[TRANSITION_SYMBOL (sp, i) - ntokens]++;
5dde5425 129 from_state[k] = s;
640748ee 130 to_state[k] = sp->states[i]->number;
d0fb370f
RS
131 }
132 }
133
afbb696d 134 free (temp_map);
d0fb370f
RS
135}
136
137
138
43591cec
AD
139/*----------------------------------------------------------.
140| Map a state/symbol pair into its numeric representation. |
141`----------------------------------------------------------*/
d0fb370f 142
60e3ecc7 143static goto_number
5dde5425 144map_goto (state_number s0, symbol_number sym)
d0fb370f 145{
60e3ecc7
PE
146 goto_number high;
147 goto_number low;
148 goto_number middle;
5dde5425 149 state_number s;
d0fb370f 150
5362cd5f
PE
151 low = goto_map[sym - ntokens];
152 high = goto_map[sym - ntokens + 1] - 1;
d0fb370f 153
58a84254 154 for (;;)
d0fb370f 155 {
58a84254
PE
156 if (high < low)
157 abort ();
d0fb370f
RS
158 middle = (low + high) / 2;
159 s = from_state[middle];
5dde5425 160 if (s == s0)
36281465 161 return middle;
5dde5425 162 else if (s < s0)
d0fb370f
RS
163 low = middle + 1;
164 else
165 high = middle - 1;
166 }
d0fb370f
RS
167}
168
169
4a120d45 170static void
d2729d44 171initialize_F (void)
d0fb370f 172{
da2a7671
PE
173 goto_number **reads = xnmalloc (ngotos, sizeof *reads);
174 goto_number *edge = xnmalloc (ngotos + 1, sizeof *edge);
60e3ecc7 175 goto_number nedges = 0;
d0fb370f 176
60e3ecc7 177 goto_number i;
d0fb370f 178
914feea9 179 F = bitsetv_create (ngotos, ntokens, BITSET_FIXED);
d0fb370f 180
d0fb370f
RS
181 for (i = 0; i < ngotos; i++)
182 {
5dde5425
PE
183 state_number stateno = to_state[i];
184 transitions *sp = states[stateno]->transitions;
d0fb370f 185
d954473d 186 int j;
640748ee 187 FOR_EACH_SHIFT (sp, j)
ccaf65bc 188 bitset_set (F[i], TRANSITION_SYMBOL (sp, j));
d0fb370f 189
ccaf65bc 190 for (; j < sp->num; j++)
d954473d 191 {
5dde5425 192 symbol_number sym = TRANSITION_SYMBOL (sp, j);
5362cd5f 193 if (nullable[sym - ntokens])
5dde5425 194 edge[nedges++] = map_goto (stateno, sym);
d954473d 195 }
a0f6b076 196
da2a7671
PE
197 if (nedges == 0)
198 reads[i] = NULL;
199 else
d954473d 200 {
da2a7671
PE
201 reads[i] = xnmalloc (nedges + 1, sizeof reads[i][0]);
202 memcpy (reads[i], edge, nedges * sizeof edge[0]);
60e3ecc7 203 reads[i][nedges] = END_NODE;
d954473d 204 nedges = 0;
d0fb370f 205 }
d0fb370f
RS
206 }
207
0e4d5753 208 relation_digraph (reads, ngotos, &F);
d0fb370f
RS
209
210 for (i = 0; i < ngotos; i++)
afbb696d 211 free (reads[i]);
d0fb370f 212
afbb696d
PE
213 free (reads);
214 free (edge);
d0fb370f
RS
215}
216
217
4a120d45 218static void
60e3ecc7 219add_lookback_edge (state *s, rule *r, goto_number gotono)
d0fb370f 220{
5dde5425 221 int ri = state_reduction_find (s, r);
da2a7671 222 goto_list *sp = xmalloc (sizeof *sp);
8dd162d3 223 sp->next = lookback[(s->reductions->look_ahead_tokens - LA) + ri];
d0fb370f 224 sp->value = gotono;
8dd162d3 225 lookback[(s->reductions->look_ahead_tokens - LA) + ri] = sp;
d0fb370f
RS
226}
227
228
d0fb370f 229
4a120d45 230static void
720d742f 231build_relations (void)
d0fb370f 232{
da2a7671
PE
233 goto_number *edge = xnmalloc (ngotos + 1, sizeof *edge);
234 state_number *states1 = xnmalloc (ritem_longest_rhs () + 1, sizeof *states1);
60e3ecc7 235 goto_number i;
720d742f 236
da2a7671 237 includes = xnmalloc (ngotos, sizeof *includes);
d0fb370f
RS
238
239 for (i = 0; i < ngotos; i++)
240 {
9887c18a 241 int nedges = 0;
5dde5425
PE
242 symbol_number symbol1 = states[to_state[i]]->accessing_symbol;
243 rule **rulep;
d0fb370f 244
5362cd5f 245 for (rulep = derives[symbol1 - ntokens]; *rulep; rulep++)
720d742f 246 {
d0829076 247 bool done;
80a69750 248 int length = 1;
5dde5425
PE
249 item_number *rp;
250 state *s = states[from_state[i]];
251 states1[0] = s->number;
d0fb370f 252
bb0027a9 253 for (rp = (*rulep)->rhs; *rp >= 0; rp++)
720d742f 254 {
5dde5425
PE
255 s = transitions_to (s->transitions,
256 item_number_as_symbol_number (*rp));
257 states1[length++] = s->number;
720d742f
AD
258 }
259
5dde5425
PE
260 if (!s->consistent)
261 add_lookback_edge (s, *rulep, i);
720d742f
AD
262
263 length--;
d0829076 264 done = false;
720d742f
AD
265 while (!done)
266 {
d0829076 267 done = true;
720d742f
AD
268 rp--;
269 /* JF added rp>=ritem && I hope to god its right! */
270 if (rp >= ritem && ISVAR (*rp))
271 {
5dde5425 272 /* Downcasting from item_number to symbol_number. */
5fbb0954 273 edge[nedges++] = map_goto (states1[--length],
a49aecd5 274 item_number_as_symbol_number (*rp));
5362cd5f 275 if (nullable[*rp - ntokens])
d0829076 276 done = false;
720d742f
AD
277 }
278 }
d0fb370f
RS
279 }
280
da2a7671
PE
281 if (nedges == 0)
282 includes[i] = NULL;
283 else
720d742f 284 {
9887c18a 285 int j;
da2a7671 286 includes[i] = xnmalloc (nedges + 1, sizeof includes[i][0]);
720d742f 287 for (j = 0; j < nedges; j++)
80a69750 288 includes[i][j] = edge[j];
60e3ecc7 289 includes[i][nedges] = END_NODE;
720d742f 290 }
d0fb370f
RS
291 }
292
afbb696d
PE
293 free (edge);
294 free (states1);
9887c18a 295
0e4d5753 296 relation_transpose (&includes, ngotos);
d0fb370f
RS
297}
298
299
720d742f 300
4a120d45 301static void
720d742f 302compute_FOLLOWS (void)
d0fb370f 303{
60e3ecc7 304 goto_number i;
d0fb370f 305
0e4d5753 306 relation_digraph (includes, ngotos, &F);
d0fb370f
RS
307
308 for (i = 0; i < ngotos; i++)
afbb696d 309 free (includes[i]);
d0fb370f 310
afbb696d 311 free (includes);
d0fb370f
RS
312}
313
314
4a120d45 315static void
8dd162d3 316compute_look_ahead_tokens (void)
d0fb370f 317{
d200e455 318 size_t i;
5dde5425 319 goto_list *sp;
d0fb370f 320
d200e455 321 for (i = 0; i < nLA; i++)
ddcd5fdf 322 for (sp = lookback[i]; sp; sp = sp->next)
0fb1ffb1 323 bitset_or (LA[i], LA[i], F[sp->value]);
d0fb370f 324
ddcd5fdf 325 /* Free LOOKBACK. */
d200e455 326 for (i = 0; i < nLA; i++)
5dde5425 327 LIST_FREE (goto_list, lookback[i]);
d0fb370f 328
afbb696d 329 free (lookback);
914feea9 330 bitsetv_free (F);
720d742f 331}
d0fb370f 332
d0fb370f 333
8dd162d3
PE
334/*-----------------------------------------------------.
335| Count the number of look-ahead tokens required for S |
336| (N_LOOK_AHEAD_TOKENS member). |
337`-----------------------------------------------------*/
5edafffd 338
cd08e51e 339static int
8dd162d3 340state_look_ahead_tokens_count (state *s)
5edafffd 341{
cd08e51e 342 int k;
8dd162d3 343 int n_look_ahead_tokens = 0;
5dde5425
PE
344 reductions *rp = s->reductions;
345 transitions *sp = s->transitions;
cd08e51e 346
8dd162d3 347 /* We need a look-ahead either to distinguish different
cd08e51e
AD
348 reductions (i.e., there are two or more), or to distinguish a
349 reduction from a shift. Otherwise, it is straightforward,
350 and the state is `consistent'. */
351 if (rp->num > 1
352 || (rp->num == 1 && sp->num &&
353 !TRANSITION_IS_DISABLED (sp, 0) && TRANSITION_IS_SHIFT (sp, 0)))
8dd162d3 354 n_look_ahead_tokens += rp->num;
cd08e51e 355 else
5dde5425 356 s->consistent = 1;
cd08e51e
AD
357
358 for (k = 0; k < sp->num; k++)
359 if (!TRANSITION_IS_DISABLED (sp, k) && TRANSITION_IS_ERROR (sp, k))
360 {
5dde5425 361 s->consistent = 0;
cd08e51e
AD
362 break;
363 }
3877f72b 364
8dd162d3 365 return n_look_ahead_tokens;
5edafffd
AD
366}
367
7c6b64d0 368
8dd162d3
PE
369/*-----------------------------------------------------.
370| Compute LA, NLA, and the look_ahead_tokens members. |
371`-----------------------------------------------------*/
c0263492
AD
372
373static void
cd08e51e 374initialize_LA (void)
c0263492 375{
5dde5425 376 state_number i;
cd08e51e 377 bitsetv pLA;
c0263492 378
8dd162d3 379 /* Compute the total number of reductions requiring a look-ahead. */
cd08e51e
AD
380 nLA = 0;
381 for (i = 0; i < nstates; i++)
8dd162d3 382 nLA += state_look_ahead_tokens_count (states[i]);
cd08e51e
AD
383 /* Avoid having to special case 0. */
384 if (!nLA)
385 nLA = 1;
386
387 pLA = LA = bitsetv_create (nLA, ntokens, BITSET_FIXED);
da2a7671 388 lookback = xcalloc (nLA, sizeof *lookback);
cd08e51e 389
8dd162d3
PE
390 /* Initialize the members LOOK_AHEAD_TOKENS for each state whose reductions
391 require look-ahead tokens. */
c0263492
AD
392 for (i = 0; i < nstates; i++)
393 {
8dd162d3 394 int count = state_look_ahead_tokens_count (states[i]);
cd08e51e
AD
395 if (count)
396 {
8dd162d3 397 states[i]->reductions->look_ahead_tokens = pLA;
cd08e51e
AD
398 pLA += count;
399 }
c0263492
AD
400 }
401}
402
403
8dd162d3
PE
404/*----------------------------------------------.
405| Output the look-ahead tokens for each state. |
406`----------------------------------------------*/
7c6b64d0
AD
407
408static void
8dd162d3 409look_ahead_tokens_print (FILE *out)
7c6b64d0 410{
5dde5425 411 state_number i;
602bbf31 412 int j, k;
fb9c0b33 413 fputs ("Look-ahead tokens: BEGIN\n", out);
7c6b64d0
AD
414 for (i = 0; i < nstates; ++i)
415 {
5dde5425 416 reductions *reds = states[i]->reductions;
613f5e1a 417 bitset_iterator iter;
8dd162d3 418 int n_look_ahead_tokens = 0;
cd08e51e 419
8dd162d3 420 if (reds->look_ahead_tokens)
cd08e51e 421 for (k = 0; k < reds->num; ++k)
8dd162d3
PE
422 if (reds->look_ahead_tokens[k])
423 ++n_look_ahead_tokens;
613f5e1a 424
8dd162d3
PE
425 fprintf (out, "State %d: %d look-ahead tokens\n",
426 i, n_look_ahead_tokens);
7c6b64d0 427
8dd162d3 428 if (reds->look_ahead_tokens)
cd08e51e 429 for (j = 0; j < reds->num; ++j)
8dd162d3 430 BITSET_FOR_EACH (iter, reds->look_ahead_tokens[j], k, 0)
cd08e51e 431 {
427c0dda 432 fprintf (out, " on %d (%s) -> rule %d\n",
cd08e51e
AD
433 k, symbols[k]->tag,
434 reds->rules[j]->number);
435 };
7c6b64d0 436 }
fb9c0b33 437 fputs ("Look-ahead tokens: END\n", out);
7c6b64d0
AD
438}
439
720d742f
AD
440void
441lalr (void)
442{
720d742f
AD
443 initialize_LA ();
444 set_goto_map ();
445 initialize_F ();
446 build_relations ();
447 compute_FOLLOWS ();
8dd162d3 448 compute_look_ahead_tokens ();
7c6b64d0 449
273a74fa 450 if (trace_flag & trace_sets)
8dd162d3 451 look_ahead_tokens_print (stderr);
d0fb370f 452}
3325ddc4
AD
453
454
455void
456lalr_free (void)
457{
5dde5425 458 state_number s;
3325ddc4 459 for (s = 0; s < nstates; ++s)
8dd162d3 460 states[s]->reductions->look_ahead_tokens = NULL;
3325ddc4 461 bitsetv_free (LA);
3325ddc4 462}