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