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