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