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
38 static char sccsid[] = "@(#)output.c 5.7 (Berkeley) 5/24/93";
49 static short *state_count;
74 if (rflag) write_section(tables);
75 write_section(header);
76 output_trailing_text();
78 output_semantic_actions();
79 write_section(trailer);
85 if (symbol_prefix == NULL)
90 fprintf(code_file, "#define yyparse %sparse\n", symbol_prefix);
92 fprintf(code_file, "#define yylex %slex\n", symbol_prefix);
94 fprintf(code_file, "#define yyerror %serror\n", symbol_prefix);
96 fprintf(code_file, "#define yychar %schar\n", symbol_prefix);
98 fprintf(code_file, "#define yyval %sval\n", symbol_prefix);
100 fprintf(code_file, "#define yylval %slval\n", symbol_prefix);
102 fprintf(code_file, "#define yydebug %sdebug\n", symbol_prefix);
104 fprintf(code_file, "#define yynerrs %snerrs\n", symbol_prefix);
106 fprintf(code_file, "#define yyerrflag %serrflag\n", symbol_prefix);
108 fprintf(code_file, "#define yyss %sss\n", symbol_prefix);
110 fprintf(code_file, "#define yyssp %sssp\n", symbol_prefix);
112 fprintf(code_file, "#define yyvs %svs\n", symbol_prefix);
114 fprintf(code_file, "#define yyvsp %svsp\n", symbol_prefix);
116 fprintf(code_file, "#define yylhs %slhs\n", symbol_prefix);
118 fprintf(code_file, "#define yylen %slen\n", symbol_prefix);
120 fprintf(code_file, "#define yydefred %sdefred\n", symbol_prefix);
122 fprintf(code_file, "#define yydgoto %sdgoto\n", symbol_prefix);
124 fprintf(code_file, "#define yysindex %ssindex\n", symbol_prefix);
126 fprintf(code_file, "#define yyrindex %srindex\n", symbol_prefix);
128 fprintf(code_file, "#define yygindex %sgindex\n", symbol_prefix);
130 fprintf(code_file, "#define yytable %stable\n", symbol_prefix);
132 fprintf(code_file, "#define yycheck %scheck\n", symbol_prefix);
134 fprintf(code_file, "#define yyname %sname\n", symbol_prefix);
136 fprintf(code_file, "#define yyrule %srule\n", symbol_prefix);
139 fprintf(code_file, "#define YYPREFIX \"%s\"\n", symbol_prefix);
149 fprintf(output_file, "short %slhs[] = {%42d,", symbol_prefix,
150 symbol_value[start_symbol]);
153 for (i = 3; i < nrules; i++)
157 if (!rflag) ++outline;
158 putc('\n', output_file);
164 fprintf(output_file, "%5d,", symbol_value[rlhs[i]]);
166 if (!rflag) outline += 2;
167 fprintf(output_file, "\n};\n");
169 fprintf(output_file, "short %slen[] = {%42d,", symbol_prefix, 2);
172 for (i = 3; i < nrules; i++)
176 if (!rflag) ++outline;
177 putc('\n', output_file);
183 fprintf(output_file, "%5d,", rrhs[i + 1] - rrhs[i] - 1);
185 if (!rflag) outline += 2;
186 fprintf(output_file, "\n};\n");
194 fprintf(output_file, "short %sdefred[] = {%39d,", symbol_prefix,
195 (defred[0] ? defred[0] - 2 : 0));
198 for (i = 1; i < nstates; i++)
204 if (!rflag) ++outline;
205 putc('\n', output_file);
209 fprintf(output_file, "%5d,", (defred[i] ? defred[i] - 2 : 0));
212 if (!rflag) outline += 2;
213 fprintf(output_file, "\n};\n");
219 nvectors = 2*nstates + nvars;
221 froms = NEW2(nvectors, short *);
222 tos = NEW2(nvectors, short *);
223 tally = NEW2(nvectors, short);
224 width = NEW2(nvectors, short);
230 FREE(accessing_symbol);
233 FREE(goto_map + ntokens);
248 register int shiftcount, reducecount;
249 register int max, min;
250 register short *actionrow, *r, *s;
253 actionrow = NEW2(2*ntokens, short);
254 for (i = 0; i < nstates; ++i)
258 for (j = 0; j < 2*ntokens; ++j)
263 for (p = parser[i]; p; p = p->next)
265 if (p->suppressed == 0)
267 if (p->action_code == SHIFT)
270 actionrow[p->symbol] = p->number;
272 else if (p->action_code == REDUCE && p->number != defred[i])
275 actionrow[p->symbol + ntokens] = p->number;
280 tally[i] = shiftcount;
281 tally[nstates+i] = reducecount;
283 width[nstates+i] = 0;
286 froms[i] = r = NEW2(shiftcount, short);
287 tos[i] = s = NEW2(shiftcount, short);
290 for (j = 0; j < ntokens; ++j)
294 if (min > symbol_value[j])
295 min = symbol_value[j];
296 if (max < symbol_value[j])
297 max = symbol_value[j];
298 *r++ = symbol_value[j];
302 width[i] = max - min + 1;
306 froms[nstates+i] = r = NEW2(reducecount, short);
307 tos[nstates+i] = s = NEW2(reducecount, short);
310 for (j = 0; j < ntokens; ++j)
312 if (actionrow[ntokens+j])
314 if (min > symbol_value[j])
315 min = symbol_value[j];
316 if (max < symbol_value[j])
317 max = symbol_value[j];
318 *r++ = symbol_value[j];
319 *s++ = actionrow[ntokens+j] - 2;
322 width[nstates+i] = max - min + 1;
331 register int i, j, k;
333 state_count = NEW2(nstates, short);
335 k = default_goto(start_symbol + 1);
336 fprintf(output_file, "short %sdgoto[] = {%40d,", symbol_prefix, k);
337 save_column(start_symbol + 1, k);
340 for (i = start_symbol + 2; i < nsyms; i++)
344 if (!rflag) ++outline;
345 putc('\n', output_file);
352 fprintf(output_file, "%5d,", k);
356 if (!rflag) outline += 2;
357 fprintf(output_file, "\n};\n");
368 register int default_state;
371 m = goto_map[symbol];
372 n = goto_map[symbol + 1];
374 if (m == n) return (0);
376 for (i = 0; i < nstates; i++)
379 for (i = m; i < n; i++)
380 state_count[to_state[i]]++;
384 for (i = 0; i < nstates; i++)
386 if (state_count[i] > max)
388 max = state_count[i];
393 return (default_state);
398 save_column(symbol, default_state)
411 m = goto_map[symbol];
412 n = goto_map[symbol + 1];
415 for (i = m; i < n; i++)
417 if (to_state[i] != default_state)
420 if (count == 0) return;
422 symno = symbol_value[symbol] + 2*nstates;
424 froms[symno] = sp1 = sp = NEW2(count, short);
425 tos[symno] = sp2 = NEW2(count, short);
427 for (i = m; i < n; i++)
429 if (to_state[i] != default_state)
431 *sp1++ = from_state[i];
432 *sp2++ = to_state[i];
436 tally[symno] = count;
437 width[symno] = sp1[-1] - sp[0] + 1;
448 order = NEW2(nvectors, short);
451 for (i = 0; i < nvectors; i++)
459 while (j >= 0 && (width[order[j]] < w))
462 while (j >= 0 && (width[order[j]] == w) && (tally[order[j]] < t))
465 for (k = nentries - 1; k > j; k--)
466 order[k + 1] = order[k];
481 base = NEW2(nvectors, short);
482 pos = NEW2(nentries, short);
485 table = NEW2(maxtable, short);
486 check = NEW2(maxtable, short);
491 for (i = 0; i < maxtable; i++)
494 for (i = 0; i < nentries; i++)
496 state = matching_vector(i);
499 place = pack_vector(i);
504 base[order[i]] = place;
507 for (i = 0; i < nvectors; i++)
521 /* The function matching_vector determines if the vector specified by */
522 /* the input parameter matches a previously considered vector. The */
523 /* test at the start of the function checks if the vector represents */
524 /* a row of shifts over terminal symbols or a row of reductions, or a */
525 /* column of shifts over a nonterminal symbol. Berkeley Yacc does not */
526 /* check if a column of shifts over a nonterminal symbols matches a */
527 /* previously considered vector. Because of the nature of LR parsing */
528 /* tables, no two columns can match. Therefore, the only possible */
529 /* match would be between a row and a column. Such matches are */
530 /* unlikely. Therefore, to save time, no attempt is made to see if a */
531 /* column matches a previously considered vector. */
533 /* Matching_vector is poorly designed. The test could easily be made */
534 /* faster. Also, it depends on the vectors being in a specific */
538 matching_vector(vector)
556 for (prev = vector - 1; prev >= 0; prev--)
559 if (width[j] != w || tally[j] != t)
563 for (k = 0; match && k < t; k++)
565 if (tos[j][k] != tos[i][k] || froms[j][k] != froms[i][k])
582 register int i, j, k, l;
586 register short *from;
597 j = lowzero - from[0];
598 for (k = 1; k < t; ++k)
599 if (lowzero - from[k] > j)
600 j = lowzero - from[k];
606 for (k = 0; ok && k < t; k++)
612 fatal("maximum table size exceeded");
615 do { newmax += 200; } while (newmax <= loc);
616 table = (short *) REALLOC(table, newmax*sizeof(short));
617 if (table == 0) no_space();
618 check = (short *) REALLOC(check, newmax*sizeof(short));
619 if (check == 0) no_space();
620 for (l = maxtable; l < newmax; ++l)
628 if (check[loc] != -1)
631 for (k = 0; ok && k < vector; k++)
638 for (k = 0; k < t; k++)
642 check[loc] = from[k];
643 if (loc > high) high = loc;
646 while (check[lowzero] != -1)
660 fprintf(output_file, "short %ssindex[] = {%39d,", symbol_prefix, base[0]);
663 for (i = 1; i < nstates; i++)
667 if (!rflag) ++outline;
668 putc('\n', output_file);
674 fprintf(output_file, "%5d,", base[i]);
677 if (!rflag) outline += 2;
678 fprintf(output_file, "\n};\nshort %srindex[] = {%39d,", symbol_prefix,
682 for (i = nstates + 1; i < 2*nstates; i++)
686 if (!rflag) ++outline;
687 putc('\n', output_file);
693 fprintf(output_file, "%5d,", base[i]);
696 if (!rflag) outline += 2;
697 fprintf(output_file, "\n};\nshort %sgindex[] = {%39d,", symbol_prefix,
701 for (i = 2*nstates + 1; i < nvectors - 1; i++)
705 if (!rflag) ++outline;
706 putc('\n', output_file);
712 fprintf(output_file, "%5d,", base[i]);
715 if (!rflag) outline += 2;
716 fprintf(output_file, "\n};\n");
728 fprintf(code_file, "#define YYTABLESIZE %d\n", high);
729 fprintf(output_file, "short %stable[] = {%40d,", symbol_prefix,
733 for (i = 1; i <= high; i++)
737 if (!rflag) ++outline;
738 putc('\n', output_file);
744 fprintf(output_file, "%5d,", table[i]);
747 if (!rflag) outline += 2;
748 fprintf(output_file, "\n};\n");
759 fprintf(output_file, "short %scheck[] = {%40d,", symbol_prefix,
763 for (i = 1; i <= high; i++)
767 if (!rflag) ++outline;
768 putc('\n', output_file);
774 fprintf(output_file, "%5d,", check[i]);
777 if (!rflag) outline += 2;
778 fprintf(output_file, "\n};\n");
784 is_C_identifier(name)
795 if (!isalpha(c) && c != '_' && c != '$')
797 while ((c = *++s) != '"')
799 if (!isalnum(c) && c != '_' && c != '$')
805 if (!isalpha(c) && c != '_' && c != '$')
809 if (!isalnum(c) && c != '_' && c != '$')
821 for (i = 2; i < ntokens; ++i)
824 if (is_C_identifier(s))
826 fprintf(code_file, "#define ");
827 if (dflag) fprintf(defines_file, "#define ");
831 while ((c = *++s) != '"')
834 if (dflag) putc(c, defines_file);
842 if (dflag) putc(c, defines_file);
847 fprintf(code_file, " %d\n", symbol_value[i]);
848 if (dflag) fprintf(defines_file, " %d\n", symbol_value[i]);
853 fprintf(code_file, "#define YYERRCODE %d\n", symbol_value[1]);
855 if (dflag && unionized)
858 union_file = fopen(union_file_name, "r");
859 if (union_file == NULL) open_error(union_file_name);
860 while ((c = getc(union_file)) != EOF)
861 putc(c, defines_file);
862 fprintf(defines_file, " YYSTYPE;\nextern YYSTYPE %slval;\n",
871 register FILE *in, *out;
874 text_file = fopen(text_file_name, "r");
875 if (text_file == NULL)
876 open_error(text_file_name);
878 if ((c = getc(in)) == EOF)
884 while ((c = getc(in)) != EOF)
891 fprintf(out, line_format, ++outline + 1, code_file_name);
897 register int i, j, k, max;
901 fprintf(code_file, "#define YYFINAL %d\n", final_state);
903 fprintf(code_file, "#ifndef YYDEBUG\n#define YYDEBUG %d\n#endif\n",
906 fprintf(output_file, "#ifndef YYDEBUG\n#define YYDEBUG %d\n#endif\n",
910 for (i = 2; i < ntokens; ++i)
911 if (symbol_value[i] > max)
912 max = symbol_value[i];
914 fprintf(code_file, "#define YYMAXTOKEN %d\n", max);
916 symnam = (char **) MALLOC((max+1)*sizeof(char *));
917 if (symnam == 0) no_space();
919 /* Note that it is not necessary to initialize the element */
921 for (i = 0; i < max; ++i)
923 for (i = ntokens - 1; i >= 2; --i)
924 symnam[symbol_value[i]] = symbol_name[i];
925 symnam[0] = "end-of-file";
927 if (!rflag) ++outline;
928 fprintf(output_file, "#if YYDEBUG\nchar *%sname[] = {", symbol_prefix);
930 for (i = 0; i <= max; ++i)
950 if (!rflag) ++outline;
951 putc('\n', output_file);
954 fprintf(output_file, "\"\\\"");
960 fprintf(output_file, "\\\\");
962 fprintf(output_file, "\\\\");
964 putc(*s, output_file);
967 putc(*s, output_file);
969 fprintf(output_file, "\\\"\",");
971 else if (s[0] == '\'')
978 if (!rflag) ++outline;
979 putc('\n', output_file);
982 fprintf(output_file, "\"'\\\"'\",");
1000 if (!rflag) ++outline;
1001 putc('\n', output_file);
1004 fprintf(output_file, "\"'");
1006 while (*++s != '\'')
1010 fprintf(output_file, "\\\\");
1012 fprintf(output_file, "\\\\");
1014 putc(*s, output_file);
1017 putc(*s, output_file);
1019 fprintf(output_file, "'\",");
1028 if (!rflag) ++outline;
1029 putc('\n', output_file);
1032 putc('"', output_file);
1033 do { putc(*s, output_file); } while (*++s);
1034 fprintf(output_file, "\",");
1042 if (!rflag) ++outline;
1043 putc('\n', output_file);
1046 fprintf(output_file, "0,");
1049 if (!rflag) outline += 2;
1050 fprintf(output_file, "\n};\n");
1053 if (!rflag) ++outline;
1054 fprintf(output_file, "char *%srule[] = {\n", symbol_prefix);
1055 for (i = 2; i < nrules; ++i)
1057 fprintf(output_file, "\"%s :", symbol_name[rlhs[i]]);
1058 for (j = rrhs[i]; ritem[j] > 0; ++j)
1060 s = symbol_name[ritem[j]];
1063 fprintf(output_file, " \\\"");
1069 fprintf(output_file, "\\\\\\\\");
1071 fprintf(output_file, "\\\\%c", s[1]);
1075 putc(*s, output_file);
1077 fprintf(output_file, "\\\"");
1079 else if (s[0] == '\'')
1082 fprintf(output_file, " '\\\"'");
1083 else if (s[1] == '\\')
1086 fprintf(output_file, " '\\\\\\\\");
1088 fprintf(output_file, " '\\\\%c", s[2]);
1090 while (*++s != '\'')
1091 putc(*s, output_file);
1092 putc('\'', output_file);
1095 fprintf(output_file, " '%c'", s[1]);
1098 fprintf(output_file, " %s", s);
1100 if (!rflag) ++outline;
1101 fprintf(output_file, "\",\n");
1104 if (!rflag) outline += 2;
1105 fprintf(output_file, "};\n#endif\n");
1111 if (!unionized && ntags == 0)
1114 fprintf(code_file, "#ifndef YYSTYPE\ntypedef int YYSTYPE;\n#endif\n");
1119 output_trailing_text()
1121 register int c, last;
1122 register FILE *in, *out;
1133 if ((c = getc(in)) == EOF)
1138 fprintf(out, line_format, lineno, input_file_name);
1150 fprintf(out, line_format, lineno, input_file_name);
1152 do { putc(c, out); } while ((c = *++cptr) != '\n');
1158 while ((c = getc(in)) != EOF)
1172 fprintf(out, line_format, ++outline + 1, code_file_name);
1176 output_semantic_actions()
1178 register int c, last;
1181 fclose(action_file);
1182 action_file = fopen(action_file_name, "r");
1183 if (action_file == NULL)
1184 open_error(action_file_name);
1186 if ((c = getc(action_file)) == EOF)
1194 while ((c = getc(action_file)) != EOF)
1209 fprintf(out, line_format, ++outline + 1, code_file_name);
1215 register core *cp, *next;
1218 for (cp = first_state; cp; cp = next)
1228 register shifts *sp, *next;
1231 for (sp = first_shift; sp; sp = next)
1242 register reductions *rp, *next;
1244 FREE(reduction_table);
1245 for (rp = first_reduction; rp; rp = next)