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