2 * Copyright (c) 1989 The Regents of the University of California.
5 * This code is derived from software contributed to Berkeley by
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * $FreeBSD: src/usr.bin/yacc/output.c,v 1.13.2.3 2001/10/05 03:03:14 obrien Exp $
38 * @(#)output.c 5.7 (Berkeley) 5/24/93
45 static int default_goto(int);
46 static void free_itemsets(void);
47 static void free_reductions(void);
48 static void free_shifts(void);
49 static void goto_actions(void);
50 static int is_C_identifier(char *);
51 static int matching_vector(int);
52 static void output_actions(void);
53 static void output_base(void);
54 static void output_check(void);
55 static void output_debug(void);
56 static void output_defines(void);
57 static void output_prefix(void);
58 static void output_rule_data(void);
59 static void output_semantic_actions(void);
60 static void output_stored_text(void);
61 static void output_stype(void);
62 static void output_table(void);
63 static void output_trailing_text(void);
64 static void output_yydefred(void);
65 static void pack_table(void);
66 static int pack_vector(int);
67 static void save_column(int, int);
68 static void sort_actions(void);
69 static void token_actions(void);
70 static int increase_maxtable(int);
72 static const char line_format[] = "#line %d \"%s\"\n";
79 static short *state_count;
105 if (rflag) write_section(tables);
106 write_section(header);
107 output_trailing_text();
109 output_semantic_actions();
110 write_section(trailer);
117 if (symbol_prefix == NULL)
118 symbol_prefix = "yy";
122 fprintf(code_file, "#define yyparse %sparse\n", symbol_prefix);
124 fprintf(code_file, "#define yylex %slex\n", symbol_prefix);
126 fprintf(code_file, "#define yyerror %serror\n", symbol_prefix);
128 fprintf(code_file, "#define yychar %schar\n", symbol_prefix);
130 fprintf(code_file, "#define yyval %sval\n", symbol_prefix);
132 fprintf(code_file, "#define yylval %slval\n", symbol_prefix);
134 fprintf(code_file, "#define yydebug %sdebug\n", symbol_prefix);
136 fprintf(code_file, "#define yynerrs %snerrs\n", symbol_prefix);
138 fprintf(code_file, "#define yyerrflag %serrflag\n", symbol_prefix);
140 fprintf(code_file, "#define yyss %sss\n", symbol_prefix);
142 fprintf(code_file, "#define yyssp %sssp\n", symbol_prefix);
144 fprintf(code_file, "#define yyvs %svs\n", symbol_prefix);
146 fprintf(code_file, "#define yyvsp %svsp\n", symbol_prefix);
148 fprintf(code_file, "#define yylhs %slhs\n", symbol_prefix);
150 fprintf(code_file, "#define yylen %slen\n", symbol_prefix);
152 fprintf(code_file, "#define yydefred %sdefred\n", symbol_prefix);
154 fprintf(code_file, "#define yydgoto %sdgoto\n", symbol_prefix);
156 fprintf(code_file, "#define yysindex %ssindex\n", symbol_prefix);
158 fprintf(code_file, "#define yyrindex %srindex\n", symbol_prefix);
160 fprintf(code_file, "#define yygindex %sgindex\n", symbol_prefix);
162 fprintf(code_file, "#define yytable %stable\n", symbol_prefix);
164 fprintf(code_file, "#define yycheck %scheck\n", symbol_prefix);
166 fprintf(code_file, "#define yyname %sname\n", symbol_prefix);
168 fprintf(code_file, "#define yyrule %srule\n", symbol_prefix);
170 fprintf(code_file, "#define yysslim %ssslim\n", symbol_prefix);
172 fprintf(code_file, "#define yystacksize %sstacksize\n", symbol_prefix);
175 fprintf(code_file, "#define YYPREFIX \"%s\"\n", symbol_prefix);
180 output_rule_data(void)
186 fprintf(output_file, "const short %slhs[] = {%42d,", symbol_prefix,
187 symbol_value[start_symbol]);
190 for (i = 3; i < nrules; i++)
194 if (!rflag) ++outline;
195 putc('\n', output_file);
201 fprintf(output_file, "%5d,", symbol_value[rlhs[i]]);
203 if (!rflag) outline += 2;
204 fprintf(output_file, "\n};\n");
206 fprintf(output_file, "const short %slen[] = {%42d,", symbol_prefix, 2);
209 for (i = 3; i < nrules; i++)
213 if (!rflag) ++outline;
214 putc('\n', output_file);
220 fprintf(output_file, "%5d,", rrhs[i + 1] - rrhs[i] - 1);
222 if (!rflag) outline += 2;
223 fprintf(output_file, "\n};\n");
228 output_yydefred(void)
232 fprintf(output_file, "const short %sdefred[] = {%39d,", symbol_prefix,
233 (defred[0] ? defred[0] - 2 : 0));
236 for (i = 1; i < nstates; i++)
242 if (!rflag) ++outline;
243 putc('\n', output_file);
247 fprintf(output_file, "%5d,", (defred[i] ? defred[i] - 2 : 0));
250 if (!rflag) outline += 2;
251 fprintf(output_file, "\n};\n");
258 nvectors = 2*nstates + nvars;
260 froms = NEW2(nvectors, short *);
261 tos = NEW2(nvectors, short *);
262 tally = NEW2(nvectors, short);
263 width = NEW2(nvectors, short);
269 FREE(accessing_symbol);
272 FREE(goto_map + ntokens);
288 int shiftcount, reducecount;
290 short *actionrow, *r, *s;
293 actionrow = NEW2(2*ntokens, short);
294 for (i = 0; i < nstates; ++i)
298 for (j = 0; j < 2*ntokens; ++j)
303 for (p = parser[i]; p; p = p->next)
305 if (p->suppressed == 0)
307 if (p->action_code == SHIFT)
310 actionrow[p->symbol] = p->number;
312 else if (p->action_code == REDUCE && p->number != defred[i])
315 actionrow[p->symbol + ntokens] = p->number;
320 tally[i] = shiftcount;
321 tally[nstates+i] = reducecount;
323 width[nstates+i] = 0;
326 froms[i] = r = NEW2(shiftcount, short);
327 tos[i] = s = NEW2(shiftcount, short);
330 for (j = 0; j < ntokens; ++j)
334 if (min > symbol_value[j])
335 min = symbol_value[j];
336 if (max < symbol_value[j])
337 max = symbol_value[j];
338 *r++ = symbol_value[j];
342 width[i] = max - min + 1;
346 froms[nstates+i] = r = NEW2(reducecount, short);
347 tos[nstates+i] = s = NEW2(reducecount, short);
350 for (j = 0; j < ntokens; ++j)
352 if (actionrow[ntokens+j])
354 if (min > symbol_value[j])
355 min = symbol_value[j];
356 if (max < symbol_value[j])
357 max = symbol_value[j];
358 *r++ = symbol_value[j];
359 *s++ = actionrow[ntokens+j] - 2;
362 width[nstates+i] = max - min + 1;
374 state_count = NEW2(nstates, short);
376 k = default_goto(start_symbol + 1);
377 fprintf(output_file, "const short %sdgoto[] = {%40d,", symbol_prefix, k);
378 save_column(start_symbol + 1, k);
381 for (i = start_symbol + 2; i < nsyms; i++)
385 if (!rflag) ++outline;
386 putc('\n', output_file);
393 fprintf(output_file, "%5d,", k);
397 if (!rflag) outline += 2;
398 fprintf(output_file, "\n};\n");
403 default_goto(int symbol)
411 m = goto_map[symbol];
412 n = goto_map[symbol + 1];
414 if (m == n) return (0);
416 for (i = 0; i < nstates; i++)
419 for (i = m; i < n; i++)
420 state_count[to_state[i]]++;
424 for (i = 0; i < nstates; i++)
426 if (state_count[i] > max)
428 max = state_count[i];
433 return (default_state);
439 save_column(int symbol, int default_state)
450 m = goto_map[symbol];
451 n = goto_map[symbol + 1];
454 for (i = m; i < n; i++)
456 if (to_state[i] != default_state)
459 if (count == 0) return;
461 symno = symbol_value[symbol] + 2*nstates;
463 froms[symno] = sp1 = sp = NEW2(count, short);
464 tos[symno] = sp2 = NEW2(count, short);
466 for (i = m; i < n; i++)
468 if (to_state[i] != default_state)
470 *sp1++ = from_state[i];
471 *sp2++ = to_state[i];
475 tally[symno] = count;
476 width[symno] = sp1[-1] - sp[0] + 1;
488 order = NEW2(nvectors, short);
491 for (i = 0; i < nvectors; i++)
499 while (j >= 0 && (width[order[j]] < w))
502 while (j >= 0 && (width[order[j]] == w) && (tally[order[j]] < t))
505 for (k = nentries - 1; k > j; k--)
506 order[k + 1] = order[k];
522 base = NEW2(nvectors, short);
523 pos = NEW2(nentries, short);
526 table = NEW2(maxtable, short);
527 check = NEW2(maxtable, short);
532 for (i = 0; i < maxtable; i++)
535 for (i = 0; i < nentries; i++)
537 state = matching_vector(i);
540 place = pack_vector(i);
545 base[order[i]] = place;
548 for (i = 0; i < nvectors; i++)
562 /* The function matching_vector determines if the vector specified by */
563 /* the input parameter matches a previously considered vector. The */
564 /* test at the start of the function checks if the vector represents */
565 /* a row of shifts over terminal symbols or a row of reductions, or a */
566 /* column of shifts over a nonterminal symbol. Berkeley Yacc does not */
567 /* check if a column of shifts over a nonterminal symbols matches a */
568 /* previously considered vector. Because of the nature of LR parsing */
569 /* tables, no two columns can match. Therefore, the only possible */
570 /* match would be between a row and a column. Such matches are */
571 /* unlikely. Therefore, to save time, no attempt is made to see if a */
572 /* column matches a previously considered vector. */
574 /* Matching_vector is poorly designed. The test could easily be made */
575 /* faster. Also, it depends on the vectors being in a specific */
579 matching_vector(int vector)
596 for (prev = vector - 1; prev >= 0; prev--)
599 if (width[j] != w || tally[j] != t)
603 for (k = 0; match && k < t; k++)
605 if (tos[j][k] != tos[i][k] || froms[j][k] != froms[i][k])
619 pack_vector(int vector)
635 j = lowzero - from[0];
636 for (k = 1; k < t; ++k)
637 if (lowzero - from[k] > j)
638 j = lowzero - from[k];
644 for (k = 0; ok && k < t; k++)
650 fatal("maximum table size exceeded");
651 maxtable = increase_maxtable(loc);
654 if (check[loc] != -1)
657 for (k = 0; ok && k < vector; k++)
664 for (k = 0; k < t; k++)
668 check[loc] = from[k];
669 if (loc > high) high = loc;
672 while (check[lowzero] != -1)
674 if (lowzero >= maxtable)
676 if (lowzero >= MAXTABLE)
678 fatal("maximum table size exceeded in check\n");
681 maxtable = increase_maxtable(loc);
699 fprintf(output_file, "const short %ssindex[] = {%39d,", symbol_prefix,
703 for (i = 1; i < nstates; i++)
707 if (!rflag) ++outline;
708 putc('\n', output_file);
714 fprintf(output_file, "%5d,", base[i]);
717 if (!rflag) outline += 2;
718 fprintf(output_file, "\n};\nconst short %srindex[] = {%39d,", symbol_prefix,
722 for (i = nstates + 1; i < 2*nstates; i++)
726 if (!rflag) ++outline;
727 putc('\n', output_file);
733 fprintf(output_file, "%5d,", base[i]);
736 if (!rflag) outline += 2;
737 fprintf(output_file, "\n};\nconst short %sgindex[] = {%39d,", symbol_prefix,
741 for (i = 2*nstates + 1; i < nvectors - 1; i++)
745 if (!rflag) ++outline;
746 putc('\n', output_file);
752 fprintf(output_file, "%5d,", base[i]);
755 if (!rflag) outline += 2;
756 fprintf(output_file, "\n};\n");
769 fprintf(code_file, "#define YYTABLESIZE %d\n", high);
770 fprintf(output_file, "const short %stable[] = {%40d,", symbol_prefix,
774 for (i = 1; i <= high; i++)
778 if (!rflag) ++outline;
779 putc('\n', output_file);
785 fprintf(output_file, "%5d,", table[i]);
788 if (!rflag) outline += 2;
789 fprintf(output_file, "\n};\n");
801 fprintf(output_file, "const short %scheck[] = {%40d,", symbol_prefix,
805 for (i = 1; i <= high; i++)
809 if (!rflag) ++outline;
810 putc('\n', output_file);
816 fprintf(output_file, "%5d,", check[i]);
819 if (!rflag) outline += 2;
820 fprintf(output_file, "\n};\n");
826 is_C_identifier(char *name)
836 if (!isalpha(c) && c != '_' && c != '$')
838 while ((c = *++s) != '"')
840 if (!isalnum(c) && c != '_' && c != '$')
846 if (!isalpha(c) && c != '_' && c != '$')
850 if (!isalnum(c) && c != '_' && c != '$')
864 fprintf(code_file, "#define YYERRCODE %d\n", symbol_value[1]);
868 fprintf(defines_file, "#ifndef YYERRCODE\n");
869 fprintf(defines_file, "#define YYERRCODE %d\n", symbol_value[1]);
870 fprintf(defines_file, "#endif\n\n");
872 for (i = 2; i < ntokens; ++i)
875 if (is_C_identifier(s))
877 fprintf(code_file, "#define ");
878 if (dflag) fprintf(defines_file, "#define ");
882 while ((c = *++s) != '"')
885 if (dflag) putc(c, defines_file);
893 if (dflag) putc(c, defines_file);
898 fprintf(code_file, " %d\n", symbol_value[i]);
899 if (dflag) fprintf(defines_file, " %d\n", symbol_value[i]);
903 if (dflag && unionized)
906 union_file = fopen(union_file_name, "r");
907 if (union_file == NULL) open_error(union_file_name);
908 while ((c = getc(union_file)) != EOF)
909 putc(c, defines_file);
910 fprintf(defines_file, " YYSTYPE;\nextern YYSTYPE %slval;\n",
917 output_stored_text(void)
923 text_file = fopen(text_file_name, "r");
924 if (text_file == NULL)
925 open_error(text_file_name);
927 if ((c = getc(in)) == EOF)
933 while ((c = getc(in)) != EOF)
940 fprintf(out, line_format, ++outline + 1, code_file_name);
948 const char **symnam, *s;
951 fprintf(code_file, "#define YYFINAL %d\n", final_state);
953 fprintf(code_file, "#ifndef YYDEBUG\n#define YYDEBUG %d\n#endif\n",
956 fprintf(output_file, "#ifndef YYDEBUG\n#define YYDEBUG %d\n#endif\n",
960 for (i = 2; i < ntokens; ++i)
961 if (symbol_value[i] > max)
962 max = symbol_value[i];
964 fprintf(code_file, "#define YYMAXTOKEN %d\n", max);
966 symnam = MALLOC((max+1)*sizeof(char *));
967 if (symnam == NULL) no_space();
969 /* Note that it is not necessary to initialize the element */
971 for (i = 0; i < max; ++i)
973 for (i = ntokens - 1; i >= 2; --i)
974 symnam[symbol_value[i]] = symbol_name[i];
975 symnam[0] = "end-of-file";
977 if (!rflag) ++outline;
978 fprintf(output_file, "#if YYDEBUG\n");
979 fprintf(output_file, "const char * const %sname[] = {", symbol_prefix);
981 for (i = 0; i <= max; ++i)
1001 if (!rflag) ++outline;
1002 putc('\n', output_file);
1005 fprintf(output_file, "\"\\\"");
1011 fprintf(output_file, "\\\\");
1013 fprintf(output_file, "\\\\");
1015 putc(*s, output_file);
1018 putc(*s, output_file);
1020 fprintf(output_file, "\\\"\",");
1022 else if (s[0] == '\'')
1029 if (!rflag) ++outline;
1030 putc('\n', output_file);
1033 fprintf(output_file, "\"'\\\"'\",");
1038 while (*++s != '\'')
1051 if (!rflag) ++outline;
1052 putc('\n', output_file);
1055 fprintf(output_file, "\"'");
1057 while (*++s != '\'')
1061 fprintf(output_file, "\\\\");
1063 fprintf(output_file, "\\\\");
1065 putc(*s, output_file);
1068 putc(*s, output_file);
1070 fprintf(output_file, "'\",");
1079 if (!rflag) ++outline;
1080 putc('\n', output_file);
1083 putc('"', output_file);
1084 do { putc(*s, output_file); } while (*++s);
1085 fprintf(output_file, "\",");
1093 if (!rflag) ++outline;
1094 putc('\n', output_file);
1097 fprintf(output_file, "0,");
1100 if (!rflag) outline += 2;
1101 fprintf(output_file, "\n};\n");
1104 if (!rflag) ++outline;
1105 fprintf(output_file, "const char * const %srule[] = {\n", symbol_prefix);
1106 for (i = 2; i < nrules; ++i)
1108 fprintf(output_file, "\"%s :", symbol_name[rlhs[i]]);
1109 for (j = rrhs[i]; ritem[j] > 0; ++j)
1111 s = symbol_name[ritem[j]];
1114 fprintf(output_file, " \\\"");
1120 fprintf(output_file, "\\\\\\\\");
1122 fprintf(output_file, "\\\\%c", s[1]);
1126 putc(*s, output_file);
1128 fprintf(output_file, "\\\"");
1130 else if (s[0] == '\'')
1133 fprintf(output_file, " '\\\"'");
1134 else if (s[1] == '\\')
1137 fprintf(output_file, " '\\\\\\\\");
1139 fprintf(output_file, " '\\\\%c", s[2]);
1141 while (*++s != '\'')
1142 putc(*s, output_file);
1143 putc('\'', output_file);
1146 fprintf(output_file, " '%c'", s[1]);
1149 fprintf(output_file, " %s", s);
1151 if (!rflag) ++outline;
1152 fprintf(output_file, "\",\n");
1155 if (!rflag) outline += 2;
1156 fprintf(output_file, "};\n#endif\n");
1163 if (!unionized && ntags == 0)
1166 fprintf(code_file, "#ifndef YYSTYPE\ntypedef int YYSTYPE;\n#endif\n");
1172 output_trailing_text(void)
1186 if ((c = getc(in)) == EOF)
1191 fprintf(out, line_format, lineno, input_file_name);
1203 fprintf(out, line_format, lineno, input_file_name);
1205 do { putc(c, out); } while ((c = *++cptr) != '\n');
1211 while ((c = getc(in)) != EOF)
1225 fprintf(out, line_format, ++outline + 1, code_file_name);
1230 output_semantic_actions(void)
1235 fclose(action_file);
1236 action_file = fopen(action_file_name, "r");
1237 if (action_file == NULL)
1238 open_error(action_file_name);
1240 if ((c = getc(action_file)) == EOF)
1248 while ((c = getc(action_file)) != EOF)
1263 fprintf(out, line_format, ++outline + 1, code_file_name);
1273 for (cp = first_state; cp; cp = next)
1287 for (sp = first_shift; sp; sp = next)
1297 free_reductions(void)
1299 reductions *rp, *next;
1301 FREE(reduction_table);
1302 for (rp = first_reduction; rp; rp = next)
1312 * inputs - loc location in table
1313 * output - size increased to
1314 * side effects - table is increase by at least 200 short words
1318 increase_maxtable(int loc)
1325 do { newmax += 200; } while (newmax <= loc);
1326 table = (short *) REALLOC(table, newmax*sizeof(short));
1327 if (table == NULL) no_space();
1328 check = (short *) REALLOC(check, newmax*sizeof(short));
1329 if (check == NULL) no_space();
1330 for (l = maxtable; l < newmax; ++l)