]> git.saurik.com Git - bison.git/blame - src/output.c
* src/closure.c (set_firsts): De-obfuscate.
[bison.git] / src / output.c
CommitLineData
c3e23647 1/* Output the generated parsing program for bison,
fabd3b43 2 Copyright 1984, 1986, 1989, 1992, 2000, 2001 Free Software Foundation, Inc.
c3e23647 3
9ee3c97b 4 This file is part of Bison, the GNU Compiler Compiler.
c3e23647 5
9ee3c97b
AD
6 Bison is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
c3e23647 10
9ee3c97b
AD
11 Bison is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
c3e23647 15
9ee3c97b
AD
16 You should have received a copy of the GNU General Public License
17 along with Bison; see the file COPYING. If not, write to the Free
18 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA. */
c3e23647
RS
20
21
6c89f1c1
AD
22/* The parser tables consist of these tables.
23 Starred ones needed only for the semantic parser.
24 Double starred are output only if switches are set.
c3e23647 25
6c89f1c1
AD
26 yytranslate = vector mapping yylex's token numbers into bison's token
27 numbers.
c3e23647 28
6c89f1c1 29 ** yytname = vector of string-names indexed by bison token number
c3e23647 30
6c89f1c1
AD
31 ** yytoknum = vector of yylex token numbers corresponding to entries
32 in yytname
c3e23647 33
6c89f1c1 34 yyrline = vector of line-numbers of all rules. For yydebug printouts.
c3e23647 35
6c89f1c1
AD
36 yyrhs = vector of items of all rules.
37 This is exactly what ritems contains. For yydebug and for semantic
38 parser.
c3e23647 39
6c89f1c1 40 yyprhs[r] = index in yyrhs of first item for rule r.
c3e23647 41
6c89f1c1 42 yyr1[r] = symbol number of symbol that rule r derives.
c3e23647 43
6c89f1c1 44 yyr2[r] = number of symbols composing right hand side of rule r.
c3e23647 45
6c89f1c1 46 * yystos[s] = the symbol number of the symbol that leads to state s.
e372befa 47
6c89f1c1
AD
48 yydefact[s] = default rule to reduce with in state s,
49 when yytable doesn't specify something else to do.
50 Zero means the default is an error.
c3e23647 51
6c89f1c1
AD
52 yydefgoto[i] = default state to go to after a reduction of a rule that
53 generates variable ntokens + i, except when yytable
54 specifies something else to do.
c3e23647 55
6c89f1c1
AD
56 yypact[s] = index in yytable of the portion describing state s.
57 The lookahead token's type is used to index that portion
58 to find out what to do.
c3e23647 59
6c89f1c1
AD
60 If the value in yytable is positive,
61 we shift the token and go to that state.
c3e23647 62
6c89f1c1 63 If the value is negative, it is minus a rule number to reduce by.
c3e23647 64
6c89f1c1 65 If the value is zero, the default action from yydefact[s] is used.
c3e23647 66
6c89f1c1
AD
67 yypgoto[i] = the index in yytable of the portion describing
68 what to do after reducing a rule that derives variable i + ntokens.
69 This portion is indexed by the parser state number, s,
70 as of before the text for this nonterminal was read.
71 The value from yytable is the state to go to if
72 the corresponding value in yycheck is s.
c3e23647 73
6c89f1c1
AD
74 yytable = a vector filled with portions for different uses,
75 found via yypact and yypgoto.
c3e23647 76
6c89f1c1
AD
77 yycheck = a vector indexed in parallel with yytable.
78 It indicates, in a roundabout way, the bounds of the
79 portion you are trying to examine.
c3e23647 80
6c89f1c1
AD
81 Suppose that the portion of yytable starts at index p
82 and the index to be examined within the portion is i.
83 Then if yycheck[p+i] != i, i is outside the bounds
84 of what is actually allocated, and the default
85 (from yydefact or yydefgoto) should be used.
86 Otherwise, yytable[p+i] should be used.
c3e23647 87
6c89f1c1
AD
88 YYFINAL = the state number of the termination state.
89 YYFLAG = most negative short int. Used to flag ??
90 YYNTBASE = ntokens.
c3e23647
RS
91*/
92
c3e23647 93#include "system.h"
8c7ebe49 94#include "obstack.h"
14d3eb9b 95#include "quotearg.h"
ceed8467 96#include "getargs.h"
c3e23647
RS
97#include "files.h"
98#include "gram.h"
b2ca4022 99#include "LR0.h"
a0f6b076 100#include "complain.h"
6c89f1c1 101#include "output.h"
720d742f 102#include "lalr.h"
a70083a3 103#include "reader.h"
0619caf0 104#include "conflicts.h"
11d82f03 105#include "muscle_tab.h"
c3e23647 106
d019d655
AD
107extern void berror PARAMS((const char *));
108
c3e23647
RS
109static int nvectors;
110static int nentries;
342b8b6e
AD
111static short **froms = NULL;
112static short **tos = NULL;
113static short *tally = NULL;
114static short *width = NULL;
115static short *actrow = NULL;
116static short *state_count = NULL;
117static short *order = NULL;
118static short *base = NULL;
119static short *pos = NULL;
120static short *table = NULL;
121static short *check = NULL;
c3e23647
RS
122static int lowzero;
123static int high;
124
11d82f03 125struct obstack muscle_obstack;
26f609ff 126struct obstack output_obstack;
c3e23647 127
c7925b99
MA
128int error_verbose = 0;
129
26f609ff 130/* FIXME. */
c3e23647 131
d019d655 132static inline void
342b8b6e
AD
133output_table_data (struct obstack *oout,
134 short *table_data,
135 short first,
136 short begin,
26f609ff 137 short end)
d019d655 138{
26f609ff
RA
139 int i;
140 int j = 1;
342b8b6e 141
26f609ff
RA
142 obstack_fgrow1 (oout, "%6d", first);
143 for (i = begin; i < end; ++i)
d019d655 144 {
896fe5c1 145 obstack_1grow (oout, ',');
d019d655
AD
146 if (j >= 10)
147 {
ff4423cc 148 obstack_sgrow (oout, "\n ");
d019d655
AD
149 j = 1;
150 }
151 else
26f609ff 152 ++j;
8f451ef7 153 obstack_fgrow1 (oout, "%6d", table_data[i]);
c3e23647 154 }
26f609ff 155 obstack_1grow (oout, 0);
c3e23647
RS
156}
157
158
4a120d45 159static void
d2729d44 160output_token_translations (void)
c3e23647 161{
342b8b6e 162 output_table_data (&output_obstack, token_translations,
26f609ff 163 0, 1, max_user_token_number + 1);
11d82f03 164 muscle_insert ("translate", obstack_finish (&output_obstack));
342b8b6e 165 XFREE (token_translations);
c3e23647
RS
166}
167
168
4a120d45 169static void
d2729d44 170output_gram (void)
c3e23647 171{
b2ed6e58
AD
172 {
173 int i;
174 short *values = XCALLOC (short, nrules + 1);
175 for (i = 0; i < nrules + 1; ++i)
176 values[i] = rule_table[i].rhs;
177 output_table_data (&output_obstack, values,
178 0, 1, nrules + 1);
179 XFREE (values);
180 }
181
11d82f03 182 muscle_insert ("prhs", obstack_finish (&output_obstack));
342b8b6e 183
1e9798d5
AD
184 {
185 size_t yyrhs_size = 1;
186 short *yyrhs, *sp;
187 int i;
c3e23647 188
1e9798d5
AD
189 for (sp = ritem + 1; *sp; sp++)
190 ++yyrhs_size;
191 yyrhs = XMALLOC (short, yyrhs_size);
c3e23647 192
1e9798d5
AD
193 for (sp = ritem + 1, i = 1; *sp; ++sp, ++i)
194 yyrhs[i] = *sp > 0 ? *sp : 0;
c3e23647 195
342b8b6e 196 output_table_data (&output_obstack, yyrhs,
26f609ff 197 ritem[0], 1, yyrhs_size);
11d82f03 198 muscle_insert ("rhs", obstack_finish (&output_obstack));
26f609ff 199
1e9798d5
AD
200 XFREE (yyrhs);
201 }
c3e23647 202
4e5caae2
MA
203#if 0
204 if (!semantic_parser && !no_parser_flag)
205 obstack_sgrow (&table_obstack, "\n#endif\n");
206#endif
c3e23647
RS
207}
208
209
4a120d45 210static void
d2729d44 211output_stos (void)
c3e23647 212{
9703cc49
AD
213 int i;
214 short *values = (short *) alloca (sizeof (short) * nstates);
215 for (i = 0; i < nstates; ++i)
216 values[i] = state_table[i].accessing_symbol;
217 output_table_data (&output_obstack, values,
26f609ff 218 0, 1, nstates);
11d82f03 219 muscle_insert ("stos", obstack_finish (&output_obstack));
c3e23647
RS
220}
221
222
4a120d45 223static void
d2729d44 224output_rule_data (void)
c3e23647 225{
6c89f1c1
AD
226 int i;
227 int j;
1e9798d5 228 short *short_tab = NULL;
c3e23647 229
e41dc700
AD
230 {
231 short *values = XCALLOC (short, nrules + 1);
232 for (i = 0; i < nrules + 1; ++i)
233 values[i] = rule_table[i].line;
234 output_table_data (&output_obstack, values,
235 0, 1, nrules + 1);
236 muscle_insert ("rline", obstack_finish (&output_obstack));
237 XFREE (values);
238 }
239
c3e23647 240
1e9798d5
AD
241 j = 0;
242 for (i = 0; i < nsyms; i++)
ceed8467
AD
243 /* this used to be i<=nsyms, but that output a final "" symbol
244 almost by accident */
c3e23647 245 {
1e9798d5
AD
246 /* Width of the next token, including the two quotes, the coma
247 and the space. */
248 int strsize = 4;
6c89f1c1 249 char *p;
c3e23647 250
1e9798d5
AD
251 for (p = tags[i]; p && *p; p++)
252 if (*p == '"' || *p == '\\' || *p == '\n' || *p == '\t'
253 || *p == '\b')
254 strsize += 2;
255 else if (*p < 040 || *p >= 0177)
256 strsize += 4;
257 else
258 strsize++;
259
260 if (j + strsize > 75)
c3e23647 261 {
26f609ff 262 obstack_sgrow (&output_obstack, "\n ");
1e9798d5 263 j = 2;
c3e23647
RS
264 }
265
26f609ff 266 obstack_1grow (&output_obstack, '\"');
c3e23647
RS
267 for (p = tags[i]; p && *p; p++)
268 {
269 if (*p == '"' || *p == '\\')
26f609ff 270 obstack_fgrow1 (&output_obstack, "\\%c", *p);
c3e23647 271 else if (*p == '\n')
26f609ff 272 obstack_sgrow (&output_obstack, "\\n");
c3e23647 273 else if (*p == '\t')
26f609ff 274 obstack_sgrow (&output_obstack, "\\t");
c3e23647 275 else if (*p == '\b')
26f609ff 276 obstack_sgrow (&output_obstack, "\\b");
c3e23647 277 else if (*p < 040 || *p >= 0177)
26f609ff 278 obstack_fgrow1 (&output_obstack, "\\%03o", *p);
c3e23647 279 else
26f609ff 280 obstack_1grow (&output_obstack, *p);
c3e23647
RS
281 }
282
26f609ff 283 obstack_sgrow (&output_obstack, "\", ");
1e9798d5 284 j += strsize;
c3e23647 285 }
9ee3c97b 286 /* add a NULL entry to list of tokens */
26f609ff 287 obstack_sgrow (&output_obstack, "NULL");
c3e23647 288
26f609ff
RA
289 /* Finish table and store. */
290 obstack_1grow (&output_obstack, 0);
11d82f03 291 muscle_insert ("tname", obstack_finish (&output_obstack));
e372befa 292
9ee3c97b 293 /* Output YYTOKNUM. */
26f609ff
RA
294 output_table_data (&output_obstack, user_toknums,
295 0, 1, ntokens + 1);
11d82f03 296 muscle_insert ("toknum", obstack_finish (&output_obstack));
e372befa 297
9ee3c97b 298 /* Output YYR1. */
b2ed6e58
AD
299 {
300 short *values = XCALLOC (short, nrules + 1);
301 for (i = 0; i < nrules + 1; ++i)
302 values[i] = rule_table[i].lhs;
303 output_table_data (&output_obstack, values,
304 0, 1, nrules + 1);
305 muscle_insert ("r1", obstack_finish (&output_obstack));
306 XFREE (values);
307 }
d019d655 308
9ee3c97b 309 /* Output YYR2. */
1e9798d5 310 short_tab = XMALLOC (short, nrules + 1);
c3e23647 311 for (i = 1; i < nrules; i++)
b2ed6e58
AD
312 short_tab[i] = rule_table[i + 1].rhs - rule_table[i].rhs - 1;
313 short_tab[nrules] = nitems - rule_table[nrules].rhs - 1;
342b8b6e 314 output_table_data (&output_obstack, short_tab,
26f609ff 315 0, 1, nrules + 1);
11d82f03 316 muscle_insert ("r2", obstack_finish (&output_obstack));
1e9798d5 317 XFREE (short_tab);
c3e23647 318
b2ed6e58 319 XFREE (rule_table + 1);
c3e23647
RS
320}
321
6c89f1c1
AD
322/*------------------------------------------------------------------.
323| Decide what to do for each type of token if seen as the lookahead |
324| token in specified state. The value returned is used as the |
325| default action (yydefact) for the state. In addition, actrow is |
326| filled with what to do for each kind of token, index by symbol |
327| number, with zero meaning do the default action. The value |
328| MINSHORT, a very negative number, means this situation is an |
329| error. The parser recognizes this value specially. |
330| |
331| This is where conflicts are resolved. The loop over lookahead |
332| rules considered lower-numbered rules last, and the last rule |
333| considered that likes a token gets to handle it. |
334`------------------------------------------------------------------*/
c3e23647 335
4a120d45 336static int
d2729d44 337action_row (int state)
c3e23647 338{
6c89f1c1
AD
339 int i;
340 int j;
341 int k;
342 int m = 0;
343 int n = 0;
6c89f1c1
AD
344 int default_rule;
345 int nreds;
6c89f1c1
AD
346 int rule;
347 int shift_state;
348 int symbol;
6c89f1c1
AD
349 reductions *redp;
350 shifts *shiftp;
351 errs *errp;
ceed8467 352 int nodefault = 0; /* set nonzero to inhibit having any default reduction */
c3e23647
RS
353
354 for (i = 0; i < ntokens; i++)
355 actrow[i] = 0;
356
357 default_rule = 0;
358 nreds = 0;
90b4416b 359 redp = state_table[state].reduction_table;
c3e23647
RS
360
361 if (redp)
362 {
363 nreds = redp->nreds;
364
365 if (nreds >= 1)
366 {
36281465
AD
367 /* loop over all the rules available here which require
368 lookahead */
f004bf6a
AD
369 m = state_table[state].lookaheads;
370 n = state_table[state + 1].lookaheads;
c3e23647
RS
371
372 for (i = n - 1; i >= m; i--)
7a5350ba
AD
373 /* and find each token which the rule finds acceptable
374 to come next */
375 for (j = 0; j < ntokens; j++)
376 /* and record this rule as the rule to use if that
377 token follows. */
378 if (BITISSET (LA (i), j))
379 actrow[j] = -LAruleno[i];
c3e23647
RS
380 }
381 }
382
36281465
AD
383 /* Now see which tokens are allowed for shifts in this state. For
384 them, record the shift as the thing to do. So shift is preferred
385 to reduce. */
d954473d 386 shiftp = state_table[state].shift_table;
d954473d 387 for (i = 0; i < shiftp->nshifts; i++)
c3e23647 388 {
d954473d
AD
389 shift_state = shiftp->shifts[i];
390 if (!shift_state)
391 continue;
c3e23647 392
d954473d 393 symbol = state_table[shift_state].accessing_symbol;
c3e23647 394
d954473d
AD
395 if (ISVAR (symbol))
396 break;
c3e23647 397
d954473d 398 actrow[symbol] = shift_state;
c3e23647 399
d954473d
AD
400 /* Do not use any default reduction if there is a shift for
401 error */
402 if (symbol == error_token_number)
403 nodefault = 1;
c3e23647
RS
404 }
405
36281465
AD
406 /* See which tokens are an explicit error in this state (due to
407 %nonassoc). For them, record MINSHORT as the action. */
d954473d 408 errp = err_table[state];
c3e23647
RS
409
410 if (errp)
411 {
412 k = errp->nerrs;
413
414 for (i = 0; i < k; i++)
415 {
416 symbol = errp->errs[i];
417 actrow[symbol] = MINSHORT;
418 }
419 }
420
36281465
AD
421 /* Now find the most common reduction and make it the default action
422 for this state. */
c3e23647 423
ceed8467 424 if (nreds >= 1 && !nodefault)
c3e23647 425 {
de326cc0 426 if (state_table[state].consistent)
c3e23647
RS
427 default_rule = redp->rules[0];
428 else
429 {
7a5350ba 430 int max = 0;
c3e23647
RS
431 for (i = m; i < n; i++)
432 {
7a5350ba 433 int count = 0;
ceed8467 434 rule = -LAruleno[i];
9ee3c97b 435
c3e23647
RS
436 for (j = 0; j < ntokens; j++)
437 {
438 if (actrow[j] == rule)
439 count++;
440 }
9ee3c97b 441
c3e23647
RS
442 if (count > max)
443 {
444 max = count;
445 default_rule = rule;
446 }
447 }
9ee3c97b 448
c3e23647
RS
449 /* actions which match the default are replaced with zero,
450 which means "use the default" */
9ee3c97b 451
c3e23647
RS
452 if (max > 0)
453 {
454 for (j = 0; j < ntokens; j++)
455 {
456 if (actrow[j] == default_rule)
457 actrow[j] = 0;
458 }
9ee3c97b 459
ceed8467 460 default_rule = -default_rule;
c3e23647
RS
461 }
462 }
463 }
464
465 /* If have no default rule, the default is an error.
466 So replace any action which says "error" with "use default". */
467
468 if (default_rule == 0)
469 for (j = 0; j < ntokens; j++)
470 {
471 if (actrow[j] == MINSHORT)
472 actrow[j] = 0;
473 }
474
36281465 475 return default_rule;
c3e23647
RS
476}
477
478
4a120d45 479static void
d2729d44 480save_row (int state)
c3e23647 481{
6c89f1c1
AD
482 int i;
483 int count;
484 short *sp;
485 short *sp1;
486 short *sp2;
c3e23647
RS
487
488 count = 0;
489 for (i = 0; i < ntokens; i++)
490 {
491 if (actrow[i] != 0)
492 count++;
493 }
494
495 if (count == 0)
496 return;
497
d7913476
AD
498 froms[state] = sp1 = sp = XCALLOC (short, count);
499 tos[state] = sp2 = XCALLOC (short, count);
c3e23647
RS
500
501 for (i = 0; i < ntokens; i++)
502 {
503 if (actrow[i] != 0)
504 {
505 *sp1++ = i;
506 *sp2++ = actrow[i];
507 }
508 }
509
510 tally[state] = count;
511 width[state] = sp1[-1] - sp[0] + 1;
512}
513
514
6c89f1c1
AD
515/*------------------------------------------------------------------.
516| Figure out the actions for the specified state, indexed by |
517| lookahead token type. |
518| |
f2acea59
AD
519| The YYDEFACT table is output now. The detailed info is saved for |
520| putting into YYTABLE later. |
6c89f1c1 521`------------------------------------------------------------------*/
c3e23647 522
4a120d45 523static void
6c89f1c1 524token_actions (void)
c3e23647 525{
6c89f1c1 526 int i;
d7913476 527 short *yydefact = XCALLOC (short, nstates);
c3e23647 528
d7913476 529 actrow = XCALLOC (short, ntokens);
f2acea59 530 for (i = 0; i < nstates; ++i)
c3e23647 531 {
f2acea59 532 yydefact[i] = action_row (i);
6c89f1c1 533 save_row (i);
c3e23647 534 }
bbb5bcc6 535
342b8b6e 536 output_table_data (&output_obstack, yydefact,
26f609ff 537 yydefact[0], 1, nstates);
11d82f03 538 muscle_insert ("defact", obstack_finish (&output_obstack));
342b8b6e 539
26f609ff 540 XFREE (actrow);
d7913476 541 XFREE (yydefact);
c3e23647
RS
542}
543
544
4a120d45 545static void
d2729d44 546save_column (int symbol, int default_state)
c3e23647 547{
6c89f1c1 548 int i;
6c89f1c1
AD
549 short *sp;
550 short *sp1;
551 short *sp2;
552 int count;
553 int symno;
c3e23647 554
43591cec
AD
555 short begin = goto_map[symbol];
556 short end = goto_map[symbol + 1];
c3e23647
RS
557
558 count = 0;
43591cec 559 for (i = begin; i < end; i++)
c3e23647
RS
560 {
561 if (to_state[i] != default_state)
562 count++;
563 }
564
565 if (count == 0)
566 return;
567
568 symno = symbol - ntokens + nstates;
569
d7913476
AD
570 froms[symno] = sp1 = sp = XCALLOC (short, count);
571 tos[symno] = sp2 = XCALLOC (short, count);
c3e23647 572
43591cec 573 for (i = begin; i < end; i++)
c3e23647
RS
574 {
575 if (to_state[i] != default_state)
576 {
577 *sp1++ = from_state[i];
578 *sp2++ = to_state[i];
579 }
580 }
581
582 tally[symno] = count;
583 width[symno] = sp1[-1] - sp[0] + 1;
584}
585
6c89f1c1
AD
586static int
587default_goto (int symbol)
588{
589 int i;
590 int m;
591 int n;
592 int default_state;
593 int max;
594
595 m = goto_map[symbol];
596 n = goto_map[symbol + 1];
597
598 if (m == n)
599 return -1;
600
601 for (i = 0; i < nstates; i++)
602 state_count[i] = 0;
603
604 for (i = m; i < n; i++)
605 state_count[to_state[i]]++;
606
607 max = 0;
608 default_state = -1;
609
610 for (i = 0; i < nstates; i++)
611 {
612 if (state_count[i] > max)
613 {
614 max = state_count[i];
615 default_state = i;
616 }
617 }
618
619 return default_state;
620}
621
622
623/*-------------------------------------------------------------------.
624| Figure out what to do after reducing with each rule, depending on |
625| the saved state from before the beginning of parsing the data that |
626| matched this rule. |
627| |
628| The YYDEFGOTO table is output now. The detailed info is saved for |
629| putting into YYTABLE later. |
630`-------------------------------------------------------------------*/
631
632static void
633goto_actions (void)
634{
43591cec 635 int i;
bbb5bcc6 636 short *yydefgoto = XMALLOC (short, nsyms - ntokens);
bbb5bcc6 637
26f609ff 638 state_count = XCALLOC (short, nstates);
43591cec 639 for (i = ntokens; i < nsyms; ++i)
6c89f1c1 640 {
43591cec
AD
641 int default_state = default_goto (i);
642 save_column (i, default_state);
643 yydefgoto[i - ntokens] = default_state;
6c89f1c1
AD
644 }
645
342b8b6e 646 output_table_data (&output_obstack, yydefgoto,
26f609ff 647 yydefgoto[0], 1, nsyms - ntokens);
11d82f03 648 muscle_insert ("defgoto", obstack_finish (&output_obstack));
43591cec 649
d7913476 650 XFREE (state_count);
43591cec 651 XFREE (yydefgoto);
6c89f1c1 652}
c3e23647
RS
653
654
9ee3c97b
AD
655/* The next few functions decide how to pack the actions and gotos
656 information into yytable. */
c3e23647 657
4a120d45 658static void
d2729d44 659sort_actions (void)
c3e23647 660{
6c89f1c1
AD
661 int i;
662 int j;
663 int k;
664 int t;
665 int w;
c3e23647 666
d7913476 667 order = XCALLOC (short, nvectors);
c3e23647
RS
668 nentries = 0;
669
670 for (i = 0; i < nvectors; i++)
671 {
672 if (tally[i] > 0)
673 {
674 t = tally[i];
675 w = width[i];
676 j = nentries - 1;
677
678 while (j >= 0 && (width[order[j]] < w))
679 j--;
680
681 while (j >= 0 && (width[order[j]] == w) && (tally[order[j]] < t))
682 j--;
683
684 for (k = nentries - 1; k > j; k--)
685 order[k + 1] = order[k];
686
687 order[j + 1] = i;
688 nentries++;
689 }
690 }
691}
692
693
4a120d45 694static int
d2729d44 695matching_state (int vector)
c3e23647 696{
6c89f1c1
AD
697 int i;
698 int j;
699 int k;
700 int t;
701 int w;
702 int match;
703 int prev;
c3e23647
RS
704
705 i = order[vector];
706 if (i >= nstates)
36281465 707 return -1;
c3e23647
RS
708
709 t = tally[i];
710 w = width[i];
711
712 for (prev = vector - 1; prev >= 0; prev--)
713 {
714 j = order[prev];
715 if (width[j] != w || tally[j] != t)
36281465 716 return -1;
c3e23647
RS
717
718 match = 1;
719 for (k = 0; match && k < t; k++)
720 {
721 if (tos[j][k] != tos[i][k] || froms[j][k] != froms[i][k])
722 match = 0;
723 }
724
725 if (match)
36281465 726 return j;
c3e23647
RS
727 }
728
36281465 729 return -1;
c3e23647
RS
730}
731
732
4a120d45 733static int
d2729d44 734pack_vector (int vector)
c3e23647 735{
6c89f1c1
AD
736 int i;
737 int j;
738 int k;
739 int t;
740 int loc = 0;
741 int ok;
742 short *from;
743 short *to;
c3e23647
RS
744
745 i = order[vector];
746 t = tally[i];
747
340ef489 748 assert (t);
c3e23647
RS
749
750 from = froms[i];
751 to = tos[i];
752
753 for (j = lowzero - from[0]; j < MAXTABLE; j++)
754 {
755 ok = 1;
756
757 for (k = 0; ok && k < t; k++)
758 {
759 loc = j + from[k];
760 if (loc > MAXTABLE)
a0f6b076 761 fatal (_("maximum table size (%d) exceeded"), MAXTABLE);
c3e23647
RS
762
763 if (table[loc] != 0)
764 ok = 0;
765 }
766
767 for (k = 0; ok && k < vector; k++)
768 {
769 if (pos[k] == j)
770 ok = 0;
771 }
772
773 if (ok)
774 {
775 for (k = 0; k < t; k++)
776 {
777 loc = j + from[k];
778 table[loc] = to[k];
779 check[loc] = from[k];
780 }
781
782 while (table[lowzero] != 0)
783 lowzero++;
784
785 if (loc > high)
786 high = loc;
787
36281465 788 return j;
c3e23647
RS
789 }
790 }
791
ceed8467
AD
792 berror ("pack_vector");
793 return 0; /* JF keep lint happy */
c3e23647
RS
794}
795
796
6c89f1c1
AD
797static void
798pack_table (void)
799{
800 int i;
801 int place;
802 int state;
803
d7913476
AD
804 base = XCALLOC (short, nvectors);
805 pos = XCALLOC (short, nentries);
806 table = XCALLOC (short, MAXTABLE);
807 check = XCALLOC (short, MAXTABLE);
6c89f1c1
AD
808
809 lowzero = 0;
810 high = 0;
811
812 for (i = 0; i < nvectors; i++)
813 base[i] = MINSHORT;
814
815 for (i = 0; i < MAXTABLE; i++)
816 check[i] = -1;
817
818 for (i = 0; i < nentries; i++)
819 {
820 state = matching_state (i);
821
822 if (state < 0)
823 place = pack_vector (i);
824 else
825 place = base[state];
826
827 pos[i] = place;
828 base[order[i]] = place;
829 }
830
831 for (i = 0; i < nvectors; i++)
832 {
833 if (froms[i])
d7913476 834 XFREE (froms[i]);
6c89f1c1 835 if (tos[i])
d7913476 836 XFREE (tos[i]);
6c89f1c1
AD
837 }
838
d7913476
AD
839 XFREE (froms);
840 XFREE (tos);
841 XFREE (pos);
6c89f1c1 842}
c3e23647
RS
843
844/* the following functions output yytable, yycheck
845 and the vectors whose elements index the portion starts */
846
4a120d45 847static void
d2729d44 848output_base (void)
c3e23647 849{
26f609ff 850 /* Output pact. */
342b8b6e 851 output_table_data (&output_obstack, base,
26f609ff 852 base[0], 1, nstates);
11d82f03 853 muscle_insert ("pact", obstack_finish (&output_obstack));
c3e23647 854
26f609ff 855 /* Output pgoto. */
342b8b6e 856 output_table_data (&output_obstack, base,
26f609ff 857 base[nstates], nstates + 1, nvectors);
11d82f03 858 muscle_insert ("pgoto", obstack_finish (&output_obstack));
c3e23647 859
d7913476 860 XFREE (base);
c3e23647
RS
861}
862
863
4a120d45 864static void
d2729d44 865output_table (void)
c3e23647 866{
342b8b6e 867 output_table_data (&output_obstack, table,
26f609ff 868 table[0], 1, high + 1);
11d82f03 869 muscle_insert ("table", obstack_finish (&output_obstack));
d7913476 870 XFREE (table);
c3e23647
RS
871}
872
873
4a120d45 874static void
d2729d44 875output_check (void)
c3e23647 876{
342b8b6e 877 output_table_data (&output_obstack, check,
26f609ff 878 check[0], 1, high + 1);
11d82f03 879 muscle_insert ("check", obstack_finish (&output_obstack));
d7913476 880 XFREE (check);
c3e23647
RS
881}
882
6c89f1c1
AD
883/* compute and output yydefact, yydefgoto, yypact, yypgoto, yytable
884 and yycheck. */
885
886static void
887output_actions (void)
888{
889 nvectors = nstates + nvars;
c3e23647 890
d7913476
AD
891 froms = XCALLOC (short *, nvectors);
892 tos = XCALLOC (short *, nvectors);
893 tally = XCALLOC (short, nvectors);
894 width = XCALLOC (short, nvectors);
6c89f1c1
AD
895
896 token_actions ();
300f275f
AD
897 LIST_FREE (shifts, first_shift);
898 LIST_FREE (reductions, first_reduction);
d7913476
AD
899 XFREE (LA);
900 XFREE (LAruleno);
6c89f1c1
AD
901
902 goto_actions ();
d7913476
AD
903 XFREE (goto_map + ntokens);
904 XFREE (from_state);
905 XFREE (to_state);
6c89f1c1
AD
906
907 sort_actions ();
908 pack_table ();
4e5caae2 909
6c89f1c1
AD
910 output_base ();
911 output_table ();
4e5caae2 912
6c89f1c1 913 output_check ();
9703cc49 914 XFREE (state_table);
6c89f1c1 915}
c3e23647 916
652def80
MA
917\f
918/*------------------------------------------------------------.
919| Copy the parser code from SKEL_FILENAME into OOUT obstack. |
920| and do the muscle substitution. |
921`------------------------------------------------------------*/
c3e23647 922
4a120d45 923static void
652def80 924output_parser (const char *skel_filename, struct obstack *oout)
c3e23647 925{
6c89f1c1 926 int c;
ff61dabd 927 FILE *fskel;
ef7ddedd 928 size_t line;
c3e23647 929
652def80 930 fskel = xfopen (skel_filename, "r");
ef7ddedd 931
e8cb70b9 932 /* New output code. */
26f609ff
RA
933 line = 1;
934 c = getc (fskel);
935 while (c != EOF)
c3e23647 936 {
26f609ff 937 if (c != '%')
573c1d9f 938 {
26f609ff
RA
939 if (c == '\n')
940 ++line;
652def80 941 obstack_1grow (oout, c);
26f609ff 942 c = getc (fskel);
bbb5bcc6 943 }
26f609ff 944 else if ((c = getc (fskel)) == '%')
bbb5bcc6 945 {
11d82f03
MA
946 /* Read the muscle. */
947 const char *muscle_key = 0;
948 const char *muscle_value = 0;
652def80 949
5b5d1929 950 while (isalnum (c = getc (fskel)) || c == '-')
11d82f03
MA
951 obstack_1grow (&muscle_obstack, c);
952 obstack_1grow (&muscle_obstack, 0);
26f609ff 953
e8cb70b9 954 /* Output the right value, or see if it's something special. */
11d82f03
MA
955 muscle_key = obstack_finish (&muscle_obstack);
956 muscle_value = muscle_find (muscle_key);
957 if (muscle_value)
652def80 958 obstack_sgrow (oout, muscle_value);
11d82f03 959 else if (!strcmp (muscle_key, "line"))
652def80 960 obstack_fgrow1 (oout, "%d", line + 1);
5b5d1929 961 else if (!strcmp (muscle_key, "input-line"))
577c6c84 962 obstack_fgrow1 (oout, "%d", lineno);
bbb5bcc6 963 else
26f609ff 964 {
652def80
MA
965 obstack_sgrow (oout, "%%");
966 obstack_sgrow (oout, muscle_key);
26f609ff 967 }
573c1d9f 968 }
b0cfa28a 969 else
652def80 970 obstack_1grow (oout, '%');
bbb5bcc6 971 }
26f609ff 972
e8cb70b9 973 /* End. */
ff61dabd 974 xfclose (fskel);
c3e23647
RS
975}
976
652def80
MA
977/*----------------------------------------.
978| Prepare the master parser to be output |
979`----------------------------------------*/
980
981static void
982output_master_parser (void)
983{
984 if (!skeleton)
985 {
986 if (semantic_parser)
987 skeleton = skeleton_find ("BISON_HAIRY", BISON_HAIRY);
988 else
989 skeleton = skeleton_find ("BISON_SIMPLE", BISON_SIMPLE);
990 }
c1ecb3c1 991 muscle_insert ("skeleton", skeleton);
652def80
MA
992 output_parser (skeleton, &table_obstack);
993}
994
995
26f609ff
RA
996/* FIXME. */
997
11d82f03
MA
998#define MUSCLE_INSERT_INT(Key, Value) \
999{ \
1000 obstack_fgrow1 (&muscle_obstack, "%d", Value); \
1001 obstack_1grow (&muscle_obstack, 0); \
1002 muscle_insert (Key, obstack_finish (&muscle_obstack)); \
26f609ff
RA
1003}
1004
11d82f03
MA
1005#define MUSCLE_INSERT_STRING(Key, Value) \
1006{ \
1007 obstack_sgrow (&muscle_obstack, Value); \
1008 obstack_1grow (&muscle_obstack, 0); \
1009 muscle_insert (Key, obstack_finish (&muscle_obstack)); \
26f609ff
RA
1010}
1011
11d82f03 1012#define MUSCLE_INSERT_PREFIX(Key, Value) \
26f609ff 1013{ \
11d82f03
MA
1014 obstack_fgrow2 (&muscle_obstack, "%s%s", spec_name_prefix, Value); \
1015 obstack_1grow (&muscle_obstack, 0); \
1016 muscle_insert (Key, obstack_finish (&muscle_obstack)); \
26f609ff
RA
1017}
1018
1019static void
1020prepare (void)
1021{
11d82f03
MA
1022 MUSCLE_INSERT_INT ("last", high);
1023 MUSCLE_INSERT_INT ("flag", MINSHORT);
1024 MUSCLE_INSERT_INT ("pure", pure_parser);
1025 MUSCLE_INSERT_INT ("nsym", nsyms);
1026 MUSCLE_INSERT_INT ("debug", debug_flag);
1027 MUSCLE_INSERT_INT ("final", final_state);
1028 MUSCLE_INSERT_INT ("maxtok", max_user_token_number);
1029 MUSCLE_INSERT_INT ("ntbase", ntokens);
c7925b99 1030 MUSCLE_INSERT_INT ("error-verbose", error_verbose);
11d82f03
MA
1031
1032 MUSCLE_INSERT_INT ("nnts", nvars);
1033 MUSCLE_INSERT_INT ("nrules", nrules);
1034 MUSCLE_INSERT_INT ("nstates", nstates);
1035 MUSCLE_INSERT_INT ("ntokens", ntokens);
1036
5b5d1929 1037 MUSCLE_INSERT_INT ("locations-flag", locations_flag);
9e644e64 1038
1c8c2190
PB
1039 /* We need to save the actions in the muscle %%action. */
1040 muscle_insert ("action", obstack_finish (&action_obstack));
1041
26f609ff 1042 if (spec_name_prefix)
11d82f03 1043 MUSCLE_INSERT_STRING ("prefix", spec_name_prefix);
26f609ff 1044}
c3e23647 1045
6c89f1c1
AD
1046/*----------------------------------------------------------.
1047| Output the parsing tables and the parser code to ftable. |
1048`----------------------------------------------------------*/
c3e23647 1049
6c89f1c1
AD
1050void
1051output (void)
1052{
26f609ff 1053 obstack_init (&output_obstack);
dd60faec 1054
300f275f 1055 LIST_FREE (core, first_state);
26f609ff 1056
6c89f1c1 1057 output_token_translations ();
6c89f1c1 1058 output_gram ();
26f609ff 1059
d7913476 1060 XFREE (ritem);
6c89f1c1
AD
1061 if (semantic_parser)
1062 output_stos ();
1063 output_rule_data ();
0846f581 1064 XFREE (user_toknums);
6c89f1c1 1065 output_actions ();
342b8b6e 1066
d8cb5183
MA
1067#if 0
1068 if (!no_parser_flag) */
1069#endif
26f609ff 1070 prepare ();
d1a2daf7 1071 /* Copy definitions in directive. */
11d82f03 1072 muscle_insert ("prologue", obstack_finish (&attrs_obstack));
652def80
MA
1073
1074 output_master_parser ();
26f609ff 1075
11d82f03 1076 obstack_free (&muscle_obstack, 0);
26f609ff 1077 obstack_free (&output_obstack, 0);
1c8c2190 1078 obstack_free (&action_obstack, 0);
c3e23647 1079}