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