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 $
37 * $DragonFly: src/usr.bin/yacc/output.c,v 1.2 2003/06/17 04:29:34 dillon Exp $
39 * @(#)output.c 5.7 (Berkeley) 5/24/93
46 static int default_goto __P((int));
47 static void free_itemsets __P((void));
48 static void free_reductions __P((void));
49 static void free_shifts __P((void));
50 static void goto_actions __P((void));
51 static int is_C_identifier __P((char *));
52 static int matching_vector __P((int));
53 static void output_actions __P((void));
54 static void output_base __P((void));
55 static void output_check __P((void));
56 static void output_debug __P((void));
57 static void output_defines __P((void));
58 static void output_prefix __P((void));
59 static void output_rule_data __P((void));
60 static void output_semantic_actions __P((void));
61 static void output_stored_text __P((void));
62 static void output_stype __P((void));
63 static void output_table __P((void));
64 static void output_trailing_text __P((void));
65 static void output_yydefred __P((void));
66 static void pack_table __P((void));
67 static int pack_vector __P((int));
68 static void save_column __P((int, int));
69 static void sort_actions __P((void));
70 static void token_actions __P((void));
71 static int increase_maxtable __P((int));
73 static const char line_format[] = "#line %d \"%s\"\n";
80 static short *state_count;
106 if (rflag) write_section(tables);
107 write_section(header);
108 output_trailing_text();
110 output_semantic_actions();
111 write_section(trailer);
118 if (symbol_prefix == NULL)
119 symbol_prefix = "yy";
123 fprintf(code_file, "#define yyparse %sparse\n", symbol_prefix);
125 fprintf(code_file, "#define yylex %slex\n", symbol_prefix);
127 fprintf(code_file, "#define yyerror %serror\n", symbol_prefix);
129 fprintf(code_file, "#define yychar %schar\n", symbol_prefix);
131 fprintf(code_file, "#define yyval %sval\n", symbol_prefix);
133 fprintf(code_file, "#define yylval %slval\n", symbol_prefix);
135 fprintf(code_file, "#define yydebug %sdebug\n", symbol_prefix);
137 fprintf(code_file, "#define yynerrs %snerrs\n", symbol_prefix);
139 fprintf(code_file, "#define yyerrflag %serrflag\n", symbol_prefix);
141 fprintf(code_file, "#define yyss %sss\n", symbol_prefix);
143 fprintf(code_file, "#define yyssp %sssp\n", symbol_prefix);
145 fprintf(code_file, "#define yyvs %svs\n", symbol_prefix);
147 fprintf(code_file, "#define yyvsp %svsp\n", symbol_prefix);
149 fprintf(code_file, "#define yylhs %slhs\n", symbol_prefix);
151 fprintf(code_file, "#define yylen %slen\n", symbol_prefix);
153 fprintf(code_file, "#define yydefred %sdefred\n", symbol_prefix);
155 fprintf(code_file, "#define yydgoto %sdgoto\n", symbol_prefix);
157 fprintf(code_file, "#define yysindex %ssindex\n", symbol_prefix);
159 fprintf(code_file, "#define yyrindex %srindex\n", symbol_prefix);
161 fprintf(code_file, "#define yygindex %sgindex\n", symbol_prefix);
163 fprintf(code_file, "#define yytable %stable\n", symbol_prefix);
165 fprintf(code_file, "#define yycheck %scheck\n", symbol_prefix);
167 fprintf(code_file, "#define yyname %sname\n", symbol_prefix);
169 fprintf(code_file, "#define yyrule %srule\n", symbol_prefix);
171 fprintf(code_file, "#define yysslim %ssslim\n", symbol_prefix);
173 fprintf(code_file, "#define yystacksize %sstacksize\n", symbol_prefix);
176 fprintf(code_file, "#define YYPREFIX \"%s\"\n", symbol_prefix);
187 fprintf(output_file, "const short %slhs[] = {%42d,", symbol_prefix,
188 symbol_value[start_symbol]);
191 for (i = 3; i < nrules; i++)
195 if (!rflag) ++outline;
196 putc('\n', output_file);
202 fprintf(output_file, "%5d,", symbol_value[rlhs[i]]);
204 if (!rflag) outline += 2;
205 fprintf(output_file, "\n};\n");
207 fprintf(output_file, "const short %slen[] = {%42d,", symbol_prefix, 2);
210 for (i = 3; i < nrules; i++)
214 if (!rflag) ++outline;
215 putc('\n', output_file);
221 fprintf(output_file, "%5d,", rrhs[i + 1] - rrhs[i] - 1);
223 if (!rflag) outline += 2;
224 fprintf(output_file, "\n};\n");
233 fprintf(output_file, "const short %sdefred[] = {%39d,", symbol_prefix,
234 (defred[0] ? defred[0] - 2 : 0));
237 for (i = 1; i < nstates; i++)
243 if (!rflag) ++outline;
244 putc('\n', output_file);
248 fprintf(output_file, "%5d,", (defred[i] ? defred[i] - 2 : 0));
251 if (!rflag) outline += 2;
252 fprintf(output_file, "\n};\n");
259 nvectors = 2*nstates + nvars;
261 froms = NEW2(nvectors, short *);
262 tos = NEW2(nvectors, short *);
263 tally = NEW2(nvectors, short);
264 width = NEW2(nvectors, short);
270 FREE(accessing_symbol);
273 FREE(goto_map + ntokens);
289 register int shiftcount, reducecount;
290 register int max, min;
291 register short *actionrow, *r, *s;
294 actionrow = NEW2(2*ntokens, short);
295 for (i = 0; i < nstates; ++i)
299 for (j = 0; j < 2*ntokens; ++j)
304 for (p = parser[i]; p; p = p->next)
306 if (p->suppressed == 0)
308 if (p->action_code == SHIFT)
311 actionrow[p->symbol] = p->number;
313 else if (p->action_code == REDUCE && p->number != defred[i])
316 actionrow[p->symbol + ntokens] = p->number;
321 tally[i] = shiftcount;
322 tally[nstates+i] = reducecount;
324 width[nstates+i] = 0;
327 froms[i] = r = NEW2(shiftcount, short);
328 tos[i] = s = NEW2(shiftcount, short);
331 for (j = 0; j < ntokens; ++j)
335 if (min > symbol_value[j])
336 min = symbol_value[j];
337 if (max < symbol_value[j])
338 max = symbol_value[j];
339 *r++ = symbol_value[j];
343 width[i] = max - min + 1;
347 froms[nstates+i] = r = NEW2(reducecount, short);
348 tos[nstates+i] = s = NEW2(reducecount, short);
351 for (j = 0; j < ntokens; ++j)
353 if (actionrow[ntokens+j])
355 if (min > symbol_value[j])
356 min = symbol_value[j];
357 if (max < symbol_value[j])
358 max = symbol_value[j];
359 *r++ = symbol_value[j];
360 *s++ = actionrow[ntokens+j] - 2;
363 width[nstates+i] = max - min + 1;
373 register int i, j, k;
375 state_count = NEW2(nstates, short);
377 k = default_goto(start_symbol + 1);
378 fprintf(output_file, "const short %sdgoto[] = {%40d,", symbol_prefix, k);
379 save_column(start_symbol + 1, k);
382 for (i = start_symbol + 2; i < nsyms; i++)
386 if (!rflag) ++outline;
387 putc('\n', output_file);
394 fprintf(output_file, "%5d,", k);
398 if (!rflag) outline += 2;
399 fprintf(output_file, "\n};\n");
410 register int default_state;
413 m = goto_map[symbol];
414 n = goto_map[symbol + 1];
416 if (m == n) return (0);
418 for (i = 0; i < nstates; i++)
421 for (i = m; i < n; i++)
422 state_count[to_state[i]]++;
426 for (i = 0; i < nstates; i++)
428 if (state_count[i] > max)
430 max = state_count[i];
435 return (default_state);
441 save_column(symbol, default_state)
454 m = goto_map[symbol];
455 n = goto_map[symbol + 1];
458 for (i = m; i < n; i++)
460 if (to_state[i] != default_state)
463 if (count == 0) return;
465 symno = symbol_value[symbol] + 2*nstates;
467 froms[symno] = sp1 = sp = NEW2(count, short);
468 tos[symno] = sp2 = NEW2(count, short);
470 for (i = m; i < n; i++)
472 if (to_state[i] != default_state)
474 *sp1++ = from_state[i];
475 *sp2++ = to_state[i];
479 tally[symno] = count;
480 width[symno] = sp1[-1] - sp[0] + 1;
492 order = NEW2(nvectors, short);
495 for (i = 0; i < nvectors; i++)
503 while (j >= 0 && (width[order[j]] < w))
506 while (j >= 0 && (width[order[j]] == w) && (tally[order[j]] < t))
509 for (k = nentries - 1; k > j; k--)
510 order[k + 1] = order[k];
526 base = NEW2(nvectors, short);
527 pos = NEW2(nentries, short);
530 table = NEW2(maxtable, short);
531 check = NEW2(maxtable, short);
536 for (i = 0; i < maxtable; i++)
539 for (i = 0; i < nentries; i++)
541 state = matching_vector(i);
544 place = pack_vector(i);
549 base[order[i]] = place;
552 for (i = 0; i < nvectors; i++)
566 /* The function matching_vector determines if the vector specified by */
567 /* the input parameter matches a previously considered vector. The */
568 /* test at the start of the function checks if the vector represents */
569 /* a row of shifts over terminal symbols or a row of reductions, or a */
570 /* column of shifts over a nonterminal symbol. Berkeley Yacc does not */
571 /* check if a column of shifts over a nonterminal symbols matches a */
572 /* previously considered vector. Because of the nature of LR parsing */
573 /* tables, no two columns can match. Therefore, the only possible */
574 /* match would be between a row and a column. Such matches are */
575 /* unlikely. Therefore, to save time, no attempt is made to see if a */
576 /* column matches a previously considered vector. */
578 /* Matching_vector is poorly designed. The test could easily be made */
579 /* faster. Also, it depends on the vectors being in a specific */
583 matching_vector(vector)
601 for (prev = vector - 1; prev >= 0; prev--)
604 if (width[j] != w || tally[j] != t)
608 for (k = 0; match && k < t; k++)
610 if (tos[j][k] != tos[i][k] || froms[j][k] != froms[i][k])
627 register int i, j, k, l;
631 register short *from;
641 j = lowzero - from[0];
642 for (k = 1; k < t; ++k)
643 if (lowzero - from[k] > j)
644 j = lowzero - from[k];
650 for (k = 0; ok && k < t; k++)
656 fatal("maximum table size exceeded");
657 maxtable = increase_maxtable(loc);
660 if (check[loc] != -1)
663 for (k = 0; ok && k < vector; k++)
670 for (k = 0; k < t; k++)
674 check[loc] = from[k];
675 if (loc > high) high = loc;
678 while (check[lowzero] != -1)
680 if (lowzero >= maxtable)
682 if (lowzero >= MAXTABLE)
684 fatal("maximum table size exceeded in check\n");
687 maxtable = increase_maxtable(loc);
705 fprintf(output_file, "const short %ssindex[] = {%39d,", symbol_prefix,
709 for (i = 1; i < nstates; i++)
713 if (!rflag) ++outline;
714 putc('\n', output_file);
720 fprintf(output_file, "%5d,", base[i]);
723 if (!rflag) outline += 2;
724 fprintf(output_file, "\n};\nconst short %srindex[] = {%39d,", symbol_prefix,
728 for (i = nstates + 1; i < 2*nstates; i++)
732 if (!rflag) ++outline;
733 putc('\n', output_file);
739 fprintf(output_file, "%5d,", base[i]);
742 if (!rflag) outline += 2;
743 fprintf(output_file, "\n};\nconst short %sgindex[] = {%39d,", symbol_prefix,
747 for (i = 2*nstates + 1; i < nvectors - 1; i++)
751 if (!rflag) ++outline;
752 putc('\n', output_file);
758 fprintf(output_file, "%5d,", base[i]);
761 if (!rflag) outline += 2;
762 fprintf(output_file, "\n};\n");
775 fprintf(code_file, "#define YYTABLESIZE %d\n", high);
776 fprintf(output_file, "const short %stable[] = {%40d,", symbol_prefix,
780 for (i = 1; i <= high; i++)
784 if (!rflag) ++outline;
785 putc('\n', output_file);
791 fprintf(output_file, "%5d,", table[i]);
794 if (!rflag) outline += 2;
795 fprintf(output_file, "\n};\n");
807 fprintf(output_file, "const short %scheck[] = {%40d,", symbol_prefix,
811 for (i = 1; i <= high; i++)
815 if (!rflag) ++outline;
816 putc('\n', output_file);
822 fprintf(output_file, "%5d,", check[i]);
825 if (!rflag) outline += 2;
826 fprintf(output_file, "\n};\n");
832 is_C_identifier(name)
843 if (!isalpha(c) && c != '_' && c != '$')
845 while ((c = *++s) != '"')
847 if (!isalnum(c) && c != '_' && c != '$')
853 if (!isalpha(c) && c != '_' && c != '$')
857 if (!isalnum(c) && c != '_' && c != '$')
871 fprintf(code_file, "#define YYERRCODE %d\n", symbol_value[1]);
875 fprintf(defines_file, "#ifndef YYERRCODE\n");
876 fprintf(defines_file, "#define YYERRCODE %d\n", symbol_value[1]);
877 fprintf(defines_file, "#endif\n\n");
879 for (i = 2; i < ntokens; ++i)
882 if (is_C_identifier(s))
884 fprintf(code_file, "#define ");
885 if (dflag) fprintf(defines_file, "#define ");
889 while ((c = *++s) != '"')
892 if (dflag) putc(c, defines_file);
900 if (dflag) putc(c, defines_file);
905 fprintf(code_file, " %d\n", symbol_value[i]);
906 if (dflag) fprintf(defines_file, " %d\n", symbol_value[i]);
910 if (dflag && unionized)
913 union_file = fopen(union_file_name, "r");
914 if (union_file == NULL) open_error(union_file_name);
915 while ((c = getc(union_file)) != EOF)
916 putc(c, defines_file);
917 fprintf(defines_file, " YYSTYPE;\nextern YYSTYPE %slval;\n",
927 register FILE *in, *out;
930 text_file = fopen(text_file_name, "r");
931 if (text_file == NULL)
932 open_error(text_file_name);
934 if ((c = getc(in)) == EOF)
940 while ((c = getc(in)) != EOF)
947 fprintf(out, line_format, ++outline + 1, code_file_name);
954 register int i, j, k, max;
958 fprintf(code_file, "#define YYFINAL %d\n", final_state);
960 fprintf(code_file, "#ifndef YYDEBUG\n#define YYDEBUG %d\n#endif\n",
963 fprintf(output_file, "#ifndef YYDEBUG\n#define YYDEBUG %d\n#endif\n",
967 for (i = 2; i < ntokens; ++i)
968 if (symbol_value[i] > max)
969 max = symbol_value[i];
971 fprintf(code_file, "#define YYMAXTOKEN %d\n", max);
973 symnam = (char **) MALLOC((max+1)*sizeof(char *));
974 if (symnam == 0) no_space();
976 /* Note that it is not necessary to initialize the element */
978 for (i = 0; i < max; ++i)
980 for (i = ntokens - 1; i >= 2; --i)
981 symnam[symbol_value[i]] = symbol_name[i];
982 symnam[0] = "end-of-file";
984 if (!rflag) ++outline;
985 fprintf(output_file, "#if YYDEBUG\n");
986 fprintf(output_file, "const char * const %sname[] = {", symbol_prefix);
988 for (i = 0; i <= max; ++i)
1008 if (!rflag) ++outline;
1009 putc('\n', output_file);
1012 fprintf(output_file, "\"\\\"");
1018 fprintf(output_file, "\\\\");
1020 fprintf(output_file, "\\\\");
1022 putc(*s, output_file);
1025 putc(*s, output_file);
1027 fprintf(output_file, "\\\"\",");
1029 else if (s[0] == '\'')
1036 if (!rflag) ++outline;
1037 putc('\n', output_file);
1040 fprintf(output_file, "\"'\\\"'\",");
1045 while (*++s != '\'')
1058 if (!rflag) ++outline;
1059 putc('\n', output_file);
1062 fprintf(output_file, "\"'");
1064 while (*++s != '\'')
1068 fprintf(output_file, "\\\\");
1070 fprintf(output_file, "\\\\");
1072 putc(*s, output_file);
1075 putc(*s, output_file);
1077 fprintf(output_file, "'\",");
1086 if (!rflag) ++outline;
1087 putc('\n', output_file);
1090 putc('"', output_file);
1091 do { putc(*s, output_file); } while (*++s);
1092 fprintf(output_file, "\",");
1100 if (!rflag) ++outline;
1101 putc('\n', output_file);
1104 fprintf(output_file, "0,");
1107 if (!rflag) outline += 2;
1108 fprintf(output_file, "\n};\n");
1111 if (!rflag) ++outline;
1112 fprintf(output_file, "const char * const %srule[] = {\n", symbol_prefix);
1113 for (i = 2; i < nrules; ++i)
1115 fprintf(output_file, "\"%s :", symbol_name[rlhs[i]]);
1116 for (j = rrhs[i]; ritem[j] > 0; ++j)
1118 s = symbol_name[ritem[j]];
1121 fprintf(output_file, " \\\"");
1127 fprintf(output_file, "\\\\\\\\");
1129 fprintf(output_file, "\\\\%c", s[1]);
1133 putc(*s, output_file);
1135 fprintf(output_file, "\\\"");
1137 else if (s[0] == '\'')
1140 fprintf(output_file, " '\\\"'");
1141 else if (s[1] == '\\')
1144 fprintf(output_file, " '\\\\\\\\");
1146 fprintf(output_file, " '\\\\%c", s[2]);
1148 while (*++s != '\'')
1149 putc(*s, output_file);
1150 putc('\'', output_file);
1153 fprintf(output_file, " '%c'", s[1]);
1156 fprintf(output_file, " %s", s);
1158 if (!rflag) ++outline;
1159 fprintf(output_file, "\",\n");
1162 if (!rflag) outline += 2;
1163 fprintf(output_file, "};\n#endif\n");
1170 if (!unionized && ntags == 0)
1173 fprintf(code_file, "#ifndef YYSTYPE\ntypedef int YYSTYPE;\n#endif\n");
1179 output_trailing_text()
1181 register int c, last;
1182 register FILE *in, *out;
1193 if ((c = getc(in)) == EOF)
1198 fprintf(out, line_format, lineno, input_file_name);
1210 fprintf(out, line_format, lineno, input_file_name);
1212 do { putc(c, out); } while ((c = *++cptr) != '\n');
1218 while ((c = getc(in)) != EOF)
1232 fprintf(out, line_format, ++outline + 1, code_file_name);
1237 output_semantic_actions()
1239 register int c, last;
1242 fclose(action_file);
1243 action_file = fopen(action_file_name, "r");
1244 if (action_file == NULL)
1245 open_error(action_file_name);
1247 if ((c = getc(action_file)) == EOF)
1255 while ((c = getc(action_file)) != EOF)
1270 fprintf(out, line_format, ++outline + 1, code_file_name);
1277 register core *cp, *next;
1280 for (cp = first_state; cp; cp = next)
1291 register shifts *sp, *next;
1294 for (sp = first_shift; sp; sp = next)
1306 register reductions *rp, *next;
1308 FREE(reduction_table);
1309 for (rp = first_reduction; rp; rp = next)
1319 * inputs - loc location in table
1320 * output - size increased to
1321 * side effects - table is increase by at least 200 short words
1325 increase_maxtable(int loc)
1332 do { newmax += 200; } while (newmax <= loc);
1333 table = (short *) REALLOC(table, newmax*sizeof(short));
1334 if (table == 0) no_space();
1335 check = (short *) REALLOC(check, newmax*sizeof(short));
1336 if (check == 0) no_space();
1337 for (l = maxtable; l < newmax; ++l)