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