1 /* $OpenBSD: output.c,v 1.28 2020/09/03 04:19:53 tb Exp $ */
2 /* $NetBSD: output.c,v 1.4 1996/03/19 03:21:41 jtc Exp $ */
3
4 /*
5 * Copyright (c) 1989 The Regents of the University of California.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by
9 * Robert Paul Corbett.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36 #include "defs.h"
37
38 static int nvectors;
39 static int nentries;
40 static short **froms;
41 static short **tos;
42 static short *tally;
43 static short *width;
44 static short *state_count;
45 static short *order;
46 static short *base;
47 static short *pos;
48 static int maxtable;
49 static short *table;
50 static short *check;
51 static int lowzero;
52 static int high;
53
54 void output_prefix(void);
55 void output_rule_data(void);
56 void output_yydefred(void);
57 void output_actions(void);
58 void token_actions(void);
59 void goto_actions(void);
60 int default_goto(int);
61 void save_column(int, int);
62 void sort_actions(void);
63 void pack_table(void);
64 int matching_vector(int);
65 int pack_vector(int);
66 void output_base(void);
67 void output_table(void);
68 void output_check(void);
69 int is_C_identifier(char *);
70 void output_defines(void);
71 void output_stored_text(void);
72 void output_debug(void);
73 void output_stype(void);
74 void output_trailing_text(void);
75 void output_semantic_actions(void);
76 void free_itemsets(void);
77 void free_shifts(void);
78 void free_reductions(void);
79
80 void
output(void)81 output(void)
82 {
83 free_itemsets();
84 free_shifts();
85 free_reductions();
86 output_prefix();
87 output_stored_text();
88 output_defines();
89 output_rule_data();
90 output_yydefred();
91 output_actions();
92 free_parser();
93 output_debug();
94 output_stype();
95 if (rflag)
96 write_section(tables);
97 write_section(header);
98 output_trailing_text();
99 write_section(body);
100 output_semantic_actions();
101 write_section(trailer);
102 }
103
104
105 void
output_prefix(void)106 output_prefix(void)
107 {
108 if (symbol_prefix == NULL)
109 symbol_prefix = "yy";
110 else {
111 ++outline;
112 fprintf(code_file, "#define yyparse %sparse\n", symbol_prefix);
113 ++outline;
114 fprintf(code_file, "#define yylex %slex\n", symbol_prefix);
115 ++outline;
116 fprintf(code_file, "#define yyerror %serror\n", symbol_prefix);
117 ++outline;
118 fprintf(code_file, "#define yychar %schar\n", symbol_prefix);
119 ++outline;
120 fprintf(code_file, "#define yyval %sval\n", symbol_prefix);
121 ++outline;
122 fprintf(code_file, "#define yylval %slval\n", symbol_prefix);
123 ++outline;
124 fprintf(code_file, "#define yydebug %sdebug\n", symbol_prefix);
125 ++outline;
126 fprintf(code_file, "#define yynerrs %snerrs\n", symbol_prefix);
127 ++outline;
128 fprintf(code_file, "#define yyerrflag %serrflag\n", symbol_prefix);
129 ++outline;
130 fprintf(code_file, "#define yyss %sss\n", symbol_prefix);
131 ++outline;
132 fprintf(code_file, "#define yysslim %ssslim\n", symbol_prefix);
133 ++outline;
134 fprintf(code_file, "#define yyssp %sssp\n", symbol_prefix);
135 ++outline;
136 fprintf(code_file, "#define yyvs %svs\n", symbol_prefix);
137 ++outline;
138 fprintf(code_file, "#define yyvsp %svsp\n", symbol_prefix);
139 ++outline;
140 fprintf(code_file, "#define yystacksize %sstacksize\n", symbol_prefix);
141 ++outline;
142 fprintf(code_file, "#define yylhs %slhs\n", symbol_prefix);
143 ++outline;
144 fprintf(code_file, "#define yylen %slen\n", symbol_prefix);
145 ++outline;
146 fprintf(code_file, "#define yydefred %sdefred\n", symbol_prefix);
147 ++outline;
148 fprintf(code_file, "#define yydgoto %sdgoto\n", symbol_prefix);
149 ++outline;
150 fprintf(code_file, "#define yysindex %ssindex\n", symbol_prefix);
151 ++outline;
152 fprintf(code_file, "#define yyrindex %srindex\n", symbol_prefix);
153 ++outline;
154 fprintf(code_file, "#define yygindex %sgindex\n", symbol_prefix);
155 ++outline;
156 fprintf(code_file, "#define yytable %stable\n", symbol_prefix);
157 ++outline;
158 fprintf(code_file, "#define yycheck %scheck\n", symbol_prefix);
159 ++outline;
160 fprintf(code_file, "#define yyname %sname\n", symbol_prefix);
161 ++outline;
162 fprintf(code_file, "#define yyrule %srule\n", symbol_prefix);
163 }
164 ++outline;
165 fprintf(code_file, "#define YYPREFIX \"%s\"\n", symbol_prefix);
166 }
167
168
169 void
output_rule_data(void)170 output_rule_data(void)
171 {
172 int i;
173 int j;
174
175 fprintf(output_file,
176 "const short %slhs[] =\n"
177 "\t{%42d,", symbol_prefix, symbol_value[start_symbol]);
178
179 j = 10;
180 for (i = 3; i < nrules; i++) {
181 if (j >= 10) {
182 if (!rflag)
183 ++outline;
184 putc('\n', output_file);
185 j = 1;
186 } else
187 ++j;
188 fprintf(output_file, "%5d,", symbol_value[rlhs[i]]);
189 }
190 if (!rflag)
191 outline += 2;
192 fprintf(output_file, "\n};\n");
193
194 fprintf(output_file,
195 "const short %slen[] =\n"
196 "\t{%42d,", symbol_prefix, 2);
197
198 j = 10;
199 for (i = 3; i < nrules; i++) {
200 if (j >= 10) {
201 if (!rflag)
202 ++outline;
203 putc('\n', output_file);
204 j = 1;
205 } else
206 j++;
207 fprintf(output_file, "%5d,", rrhs[i + 1] - rrhs[i] - 1);
208 }
209 if (!rflag)
210 outline += 2;
211 fprintf(output_file, "\n};\n");
212 }
213
214
215 void
output_yydefred(void)216 output_yydefred(void)
217 {
218 int i, j;
219
220 fprintf(output_file,
221 "const short %sdefred[] =\n"
222 "\t{%39d,",
223 symbol_prefix, (defred[0] ? defred[0] - 2 : 0));
224
225 j = 10;
226 for (i = 1; i < nstates; i++) {
227 if (j < 10)
228 ++j;
229 else {
230 if (!rflag)
231 ++outline;
232 putc('\n', output_file);
233 j = 1;
234 }
235 fprintf(output_file, "%5d,", (defred[i] ? defred[i] - 2 : 0));
236 }
237
238 if (!rflag)
239 outline += 2;
240 fprintf(output_file, "\n};\n");
241 }
242
243
244 void
output_actions(void)245 output_actions(void)
246 {
247 nvectors = 2 * nstates + nvars;
248
249 froms = NEW2(nvectors, short *);
250 tos = NEW2(nvectors, short *);
251 tally = NEW2(nvectors, short);
252 width = NEW2(nvectors, short);
253
254 token_actions();
255 free(lookaheads);
256 free(LA);
257 free(LAruleno);
258 free(accessing_symbol);
259
260 goto_actions();
261 free(goto_map + ntokens);
262 free(from_state);
263 free(to_state);
264
265 sort_actions();
266 pack_table();
267 output_base();
268 output_table();
269 output_check();
270 }
271
272
273 void
token_actions(void)274 token_actions(void)
275 {
276 int i, j;
277 int shiftcount, reducecount;
278 int max, min;
279 short *actionrow, *r, *s;
280 action *p;
281
282 actionrow = NEW2(2*ntokens, short);
283 for (i = 0; i < nstates; ++i) {
284 if (parser[i]) {
285 for (j = 0; j < 2 * ntokens; ++j)
286 actionrow[j] = 0;
287 shiftcount = 0;
288 reducecount = 0;
289 for (p = parser[i]; p; p = p->next) {
290 if (p->suppressed == 0) {
291 if (p->action_code == SHIFT) {
292 ++shiftcount;
293 actionrow[p->symbol] = p->number;
294 } else if (p->action_code == REDUCE &&
295 p->number != defred[i]) {
296 ++reducecount;
297 actionrow[p->symbol + ntokens] = p->number;
298 }
299 }
300 }
301
302 tally[i] = shiftcount;
303 tally[nstates+i] = reducecount;
304 width[i] = 0;
305 width[nstates+i] = 0;
306 if (shiftcount > 0) {
307 froms[i] = r = NEW2(shiftcount, short);
308 tos[i] = s = NEW2(shiftcount, short);
309 min = MAXSHORT;
310 max = 0;
311 for (j = 0; j < ntokens; ++j) {
312 if (actionrow[j]) {
313 if (min > symbol_value[j])
314 min = symbol_value[j];
315 if (max < symbol_value[j])
316 max = symbol_value[j];
317 *r++ = symbol_value[j];
318 *s++ = actionrow[j];
319 }
320 }
321 width[i] = max - min + 1;
322 }
323 if (reducecount > 0) {
324 froms[nstates+i] = r = NEW2(reducecount, short);
325 tos[nstates+i] = s = NEW2(reducecount, short);
326 min = MAXSHORT;
327 max = 0;
328 for (j = 0; j < ntokens; ++j) {
329 if (actionrow[ntokens+j]) {
330 if (min > symbol_value[j])
331 min = symbol_value[j];
332 if (max < symbol_value[j])
333 max = symbol_value[j];
334 *r++ = symbol_value[j];
335 *s++ = actionrow[ntokens+j] - 2;
336 }
337 }
338 width[nstates+i] = max - min + 1;
339 }
340 }
341 }
342 free(actionrow);
343 }
344
345 void
goto_actions(void)346 goto_actions(void)
347 {
348 int i, j, k;
349
350 state_count = NEW2(nstates, short);
351
352 k = default_goto(start_symbol + 1);
353 fprintf(output_file, "const short %sdgoto[] =\n"
354 "\t{%40d,", symbol_prefix, k);
355 save_column(start_symbol + 1, k);
356
357 j = 10;
358 for (i = start_symbol + 2; i < nsyms; i++) {
359 if (j >= 10) {
360 if (!rflag)
361 ++outline;
362 putc('\n', output_file);
363 j = 1;
364 } else
365 ++j;
366
367 k = default_goto(i);
368 fprintf(output_file, "%5d,", k);
369 save_column(i, k);
370 }
371
372 if (!rflag)
373 outline += 2;
374 fprintf(output_file, "\n};\n");
375 free(state_count);
376 }
377
378 int
default_goto(int symbol)379 default_goto(int symbol)
380 {
381 int i;
382 int m;
383 int n;
384 int default_state;
385 int max;
386
387 m = goto_map[symbol];
388 n = goto_map[symbol + 1];
389
390 if (m == n)
391 return (0);
392
393 memset(state_count, 0, nstates * sizeof(short));
394
395 for (i = m; i < n; i++)
396 state_count[to_state[i]]++;
397
398 max = 0;
399 default_state = 0;
400 for (i = 0; i < nstates; i++) {
401 if (state_count[i] > max) {
402 max = state_count[i];
403 default_state = i;
404 }
405 }
406
407 return (default_state);
408 }
409
410
411
412 void
save_column(int symbol,int default_state)413 save_column(int symbol, int default_state)
414 {
415 int i;
416 int m;
417 int n;
418 short *sp;
419 short *sp1;
420 short *sp2;
421 int count;
422 int symno;
423
424 m = goto_map[symbol];
425 n = goto_map[symbol + 1];
426
427 count = 0;
428 for (i = m; i < n; i++) {
429 if (to_state[i] != default_state)
430 ++count;
431 }
432 if (count == 0)
433 return;
434
435 symno = symbol_value[symbol] + 2*nstates;
436
437 froms[symno] = sp1 = sp = NEW2(count, short);
438 tos[symno] = sp2 = NEW2(count, short);
439
440 for (i = m; i < n; i++) {
441 if (to_state[i] != default_state) {
442 *sp1++ = from_state[i];
443 *sp2++ = to_state[i];
444 }
445 }
446
447 tally[symno] = count;
448 width[symno] = sp1[-1] - sp[0] + 1;
449 }
450
451 void
sort_actions(void)452 sort_actions(void)
453 {
454 int i;
455 int j;
456 int k;
457 int t;
458 int w;
459
460 order = NEW2(nvectors, short);
461 nentries = 0;
462
463 for (i = 0; i < nvectors; i++) {
464 if (tally[i] > 0) {
465 t = tally[i];
466 w = width[i];
467 j = nentries - 1;
468
469 while (j >= 0 && (width[order[j]] < w))
470 j--;
471
472 while (j >= 0 && (width[order[j]] == w) &&
473 (tally[order[j]] < t))
474 j--;
475
476 for (k = nentries - 1; k > j; k--)
477 order[k + 1] = order[k];
478
479 order[j + 1] = i;
480 nentries++;
481 }
482 }
483 }
484
485
486 void
pack_table(void)487 pack_table(void)
488 {
489 int i;
490 int place;
491 int state;
492
493 base = NEW2(nvectors, short);
494 pos = NEW2(nentries, short);
495
496 maxtable = 1000;
497 table = NEW2(maxtable, short);
498 check = NEW2(maxtable, short);
499
500 lowzero = 0;
501 high = 0;
502
503 for (i = 0; i < maxtable; i++)
504 check[i] = -1;
505
506 for (i = 0; i < nentries; i++) {
507 state = matching_vector(i);
508
509 if (state < 0)
510 place = pack_vector(i);
511 else
512 place = base[state];
513
514 pos[i] = place;
515 base[order[i]] = place;
516 }
517
518 for (i = 0; i < nvectors; i++) {
519 free(froms[i]);
520 free(tos[i]);
521 }
522
523 free(froms);
524 free(tos);
525 free(pos);
526 }
527
528
529 /* The function matching_vector determines if the vector specified by */
530 /* the input parameter matches a previously considered vector. The */
531 /* test at the start of the function checks if the vector represents */
532 /* a row of shifts over terminal symbols or a row of reductions, or a */
533 /* column of shifts over a nonterminal symbol. Berkeley Yacc does not */
534 /* check if a column of shifts over a nonterminal symbols matches a */
535 /* previously considered vector. Because of the nature of LR parsing */
536 /* tables, no two columns can match. Therefore, the only possible */
537 /* match would be between a row and a column. Such matches are */
538 /* unlikely. Therefore, to save time, no attempt is made to see if a */
539 /* column matches a previously considered vector. */
540 /* */
541 /* Matching_vector is poorly designed. The test could easily be made */
542 /* faster. Also, it depends on the vectors being in a specific */
543 /* order. */
544
545 int
matching_vector(int vector)546 matching_vector(int vector)
547 {
548 int i, j, k, t, w, match, prev;
549
550 i = order[vector];
551 if (i >= 2*nstates)
552 return (-1);
553
554 t = tally[i];
555 w = width[i];
556
557 for (prev = vector - 1; prev >= 0; prev--) {
558 j = order[prev];
559 if (width[j] != w || tally[j] != t)
560 return (-1);
561
562 match = 1;
563 for (k = 0; match && k < t; k++) {
564 if (tos[j][k] != tos[i][k] ||
565 froms[j][k] != froms[i][k])
566 match = 0;
567 }
568
569 if (match)
570 return (j);
571 }
572
573 return (-1);
574 }
575
576
577
578 int
pack_vector(int vector)579 pack_vector(int vector)
580 {
581 int i, j, k, l;
582 int t, loc, ok;
583 short *from, *to;
584 int newmax;
585
586 i = order[vector];
587 t = tally[i];
588 assert(t);
589
590 from = froms[i];
591 to = tos[i];
592
593 j = lowzero - from[0];
594 for (k = 1; k < t; ++k)
595 if (lowzero - from[k] > j)
596 j = lowzero - from[k];
597 for (;; ++j) {
598 if (j == 0)
599 continue;
600 ok = 1;
601 for (k = 0; ok && k < t; k++) {
602 loc = j + from[k];
603 if (loc >= maxtable) {
604 if (loc >= MAXTABLE)
605 fatal("maximum table size exceeded");
606
607 newmax = maxtable;
608 do {
609 newmax += 200;
610 } while (newmax <= loc);
611 table = realloc(table, newmax * sizeof(short));
612 if (table == NULL)
613 no_space();
614 check = realloc(check, newmax * sizeof(short));
615 if (check == NULL)
616 no_space();
617 for (l = maxtable; l < newmax; ++l) {
618 table[l] = 0;
619 check[l] = -1;
620 }
621 maxtable = newmax;
622 }
623
624 if (check[loc] != -1)
625 ok = 0;
626 }
627 for (k = 0; ok && k < vector; k++) {
628 if (pos[k] == j)
629 ok = 0;
630 }
631 if (ok) {
632 for (k = 0; k < t; k++) {
633 loc = j + from[k];
634 table[loc] = to[k];
635 check[loc] = from[k];
636 if (loc > high)
637 high = loc;
638 }
639
640 while (lowzero < maxtable && check[lowzero] != -1)
641 ++lowzero;
642
643 return (j);
644 }
645 }
646 }
647
648
649
650 void
output_base(void)651 output_base(void)
652 {
653 int i, j;
654
655 fprintf(output_file, "const short %ssindex[] =\n"
656 "\t{%39d,", symbol_prefix, base[0]);
657
658 j = 10;
659 for (i = 1; i < nstates; i++) {
660 if (j >= 10) {
661 if (!rflag)
662 ++outline;
663 putc('\n', output_file);
664 j = 1;
665 } else
666 ++j;
667 fprintf(output_file, "%5d,", base[i]);
668 }
669
670 if (!rflag)
671 outline += 2;
672 fprintf(output_file, "};\n"
673 "const short %srindex[] =\n"
674 "\t{%39d,", symbol_prefix, base[nstates]);
675
676 j = 10;
677 for (i = nstates + 1; i < 2*nstates; i++) {
678 if (j >= 10) {
679 if (!rflag)
680 ++outline;
681 putc('\n', output_file);
682 j = 1;
683 } else
684 ++j;
685 fprintf(output_file, "%5d,", base[i]);
686 }
687
688 if (!rflag)
689 outline += 2;
690 fprintf(output_file, "};\n"
691 "const short %sgindex[] =\n"
692 "\t{%39d,", symbol_prefix, base[2*nstates]);
693
694 j = 10;
695 for (i = 2*nstates + 1; i < nvectors - 1; i++) {
696 if (j >= 10) {
697 if (!rflag)
698 ++outline;
699 putc('\n', output_file);
700 j = 1;
701 } else
702 ++j;
703 fprintf(output_file, "%5d,", base[i]);
704 }
705
706 if (!rflag)
707 outline += 2;
708 fprintf(output_file, "\n};\n");
709 free(base);
710 }
711
712
713 void
output_table(void)714 output_table(void)
715 {
716 int i, j;
717
718 ++outline;
719 fprintf(code_file, "#define YYTABLESIZE %d\n", high);
720 fprintf(output_file, "const short %stable[] =\n"
721 "\t{%40d,", symbol_prefix, table[0]);
722
723 j = 10;
724 for (i = 1; i <= high; i++) {
725 if (j >= 10) {
726 if (!rflag)
727 ++outline;
728 putc('\n', output_file);
729 j = 1;
730 } else
731 ++j;
732 fprintf(output_file, "%5d,", table[i]);
733 }
734
735 if (!rflag)
736 outline += 2;
737 fprintf(output_file, "\n};\n");
738 free(table);
739 }
740
741
742 void
output_check(void)743 output_check(void)
744 {
745 int i, j;
746
747 fprintf(output_file, "const short %scheck[] =\n"
748 "\t{%40d,", symbol_prefix, check[0]);
749
750 j = 10;
751 for (i = 1; i <= high; i++) {
752 if (j >= 10) {
753 if (!rflag)
754 ++outline;
755 putc('\n', output_file);
756 j = 1;
757 } else
758 ++j;
759 fprintf(output_file, "%5d,", check[i]);
760 }
761
762 if (!rflag)
763 outline += 2;
764 fprintf(output_file, "\n};\n");
765 free(check);
766 }
767
768
769 int
is_C_identifier(char * name)770 is_C_identifier(char *name)
771 {
772 char *s;
773 int c;
774
775 s = name;
776 c = (unsigned char)*s;
777 if (c == '"') {
778 c = (unsigned char)*++s;
779 if (!isalpha(c) && c != '_' && c != '$')
780 return (0);
781 while ((c = (unsigned char)*++s) != '"') {
782 if (!isalnum(c) && c != '_' && c != '$')
783 return (0);
784 }
785 return (1);
786 }
787
788 if (!isalpha(c) && c != '_' && c != '$')
789 return (0);
790 while ((c = (unsigned char)*++s)) {
791 if (!isalnum(c) && c != '_' && c != '$')
792 return (0);
793 }
794 return (1);
795 }
796
797
798 void
output_defines(void)799 output_defines(void)
800 {
801 int c, i;
802 char *s;
803
804 for (i = 2; i < ntokens; ++i) {
805 s = symbol_name[i];
806 if (is_C_identifier(s)) {
807 fprintf(code_file, "#define ");
808 if (dflag)
809 fprintf(defines_file, "#define ");
810 c = (unsigned char)*s;
811 if (c == '"') {
812 while ((c = (unsigned char)*++s) != '"') {
813 putc(c, code_file);
814 if (dflag)
815 putc(c, defines_file);
816 }
817 } else {
818 do {
819 putc(c, code_file);
820 if (dflag)
821 putc(c, defines_file);
822 } while ((c = (unsigned char)*++s));
823 }
824 ++outline;
825 fprintf(code_file, " %d\n", symbol_value[i]);
826 if (dflag)
827 fprintf(defines_file, " %d\n", symbol_value[i]);
828 }
829 }
830
831 ++outline;
832 fprintf(code_file, "#define YYERRCODE %d\n", symbol_value[1]);
833
834 if (dflag && unionized) {
835 rewind(union_file);
836 while ((c = getc(union_file)) != EOF)
837 putc(c, defines_file);
838 fprintf(defines_file, " YYSTYPE;\n");
839 fprintf(defines_file, "#endif /* YYSTYPE_DEFINED */\n");
840 fprintf(defines_file, "extern YYSTYPE %slval;\n",
841 symbol_prefix);
842 }
843 }
844
845
846 void
output_stored_text(void)847 output_stored_text(void)
848 {
849 int c;
850 FILE *in, *out;
851
852 rewind(text_file);
853 in = text_file;
854 if ((c = getc(in)) == EOF)
855 return;
856 out = code_file;
857 if (c == '\n')
858 ++outline;
859 putc(c, out);
860 while ((c = getc(in)) != EOF) {
861 if (c == '\n')
862 ++outline;
863 putc(c, out);
864 }
865 if (!lflag)
866 fprintf(out, line_format, ++outline + 1, code_file_name);
867 }
868
869
870 void
output_debug(void)871 output_debug(void)
872 {
873 int i, j, k, max;
874 char **symnam, *s;
875
876 ++outline;
877 fprintf(code_file, "#define YYFINAL %d\n", final_state);
878 outline += 3;
879 fprintf(code_file, "#ifndef YYDEBUG\n#define YYDEBUG %d\n#endif\n",
880 tflag);
881 if (rflag)
882 fprintf(output_file, "#ifndef YYDEBUG\n#define YYDEBUG %d\n#endif\n",
883 tflag);
884
885 max = 0;
886 for (i = 2; i < ntokens; ++i)
887 if (symbol_value[i] > max)
888 max = symbol_value[i];
889 ++outline;
890 fprintf(code_file, "#define YYMAXTOKEN %d\n", max);
891
892 symnam = calloc(max+1, sizeof(char *));
893 if (symnam == NULL)
894 no_space();
895
896 for (i = ntokens - 1; i >= 2; --i)
897 symnam[symbol_value[i]] = symbol_name[i];
898 symnam[0] = "end-of-file";
899
900 if (!rflag)
901 ++outline;
902 fprintf(output_file,
903 "#if YYDEBUG\n"
904 "const char * const %sname[] =\n"
905 "\t{", symbol_prefix);
906 j = 80;
907 for (i = 0; i <= max; ++i) {
908 if ((s = symnam[i]) != NULL) {
909 if (s[0] == '"') {
910 k = 7;
911 while (*++s != '"') {
912 ++k;
913 if (*s == '\\') {
914 k += 2;
915 if (*++s == '\\')
916 ++k;
917 }
918 }
919 j += k;
920 if (j > 80) {
921 if (!rflag)
922 ++outline;
923 putc('\n', output_file);
924 j = k;
925 }
926 fprintf(output_file, "\"\\\"");
927 s = symnam[i];
928 while (*++s != '"') {
929 if (*s == '\\') {
930 fprintf(output_file, "\\\\");
931 if (*++s == '\\')
932 fprintf(output_file, "\\\\");
933 else
934 putc(*s, output_file);
935 } else
936 putc(*s, output_file);
937 }
938 fprintf(output_file, "\\\"\",");
939 } else if (s[0] == '\'') {
940 if (s[1] == '"') {
941 j += 7;
942 if (j > 80) {
943 if (!rflag)
944 ++outline;
945 putc('\n', output_file);
946 j = 7;
947 }
948 fprintf(output_file, "\"'\\\"'\",");
949 } else {
950 k = 5;
951 while (*++s != '\'') {
952 ++k;
953 if (*s == '\\') {
954 k += 2;
955 if (*++s == '\\')
956 ++k;
957 }
958 }
959 j += k;
960 if (j > 80) {
961 if (!rflag)
962 ++outline;
963 putc('\n', output_file);
964 j = k;
965 }
966 fprintf(output_file, "\"'");
967 s = symnam[i];
968 while (*++s != '\'') {
969 if (*s == '\\') {
970 fprintf(output_file, "\\\\");
971 if (*++s == '\\')
972 fprintf(output_file, "\\\\");
973 else
974 putc(*s, output_file);
975 } else
976 putc(*s, output_file);
977 }
978 fprintf(output_file, "'\",");
979 }
980 } else {
981 k = strlen(s) + 3;
982 j += k;
983 if (j > 80) {
984 if (!rflag)
985 ++outline;
986 putc('\n', output_file);
987 j = k;
988 }
989 putc('"', output_file);
990 do {
991 putc(*s, output_file);
992 } while (*++s);
993 fprintf(output_file, "\",");
994 }
995 } else {
996 j += 2;
997 if (j > 80) {
998 if (!rflag)
999 ++outline;
1000 putc('\n', output_file);
1001 j = 2;
1002 }
1003 fprintf(output_file, "0,");
1004 }
1005 }
1006 if (!rflag)
1007 outline += 2;
1008 fprintf(output_file, "\n};\n");
1009 free(symnam);
1010
1011 if (!rflag)
1012 ++outline;
1013 fprintf(output_file,
1014 "const char * const %srule[] =\n"
1015 "\t{", symbol_prefix);
1016 for (i = 2; i < nrules; ++i) {
1017 fprintf(output_file, "\"%s :", symbol_name[rlhs[i]]);
1018 for (j = rrhs[i]; ritem[j] > 0; ++j) {
1019 s = symbol_name[ritem[j]];
1020 if (s[0] == '"') {
1021 fprintf(output_file, " \\\"");
1022 while (*++s != '"') {
1023 if (*s == '\\') {
1024 if (s[1] == '\\')
1025 fprintf(output_file, "\\\\\\\\");
1026 else
1027 fprintf(output_file, "\\\\%c", s[1]);
1028 ++s;
1029 } else
1030 putc(*s, output_file);
1031 }
1032 fprintf(output_file, "\\\"");
1033 } else if (s[0] == '\'') {
1034 if (s[1] == '"')
1035 fprintf(output_file, " '\\\"'");
1036 else if (s[1] == '\\') {
1037 if (s[2] == '\\')
1038 fprintf(output_file, " '\\\\\\\\");
1039 else
1040 fprintf(output_file, " '\\\\%c", s[2]);
1041 s += 2;
1042 while (*++s != '\'')
1043 putc(*s, output_file);
1044 putc('\'', output_file);
1045 } else
1046 fprintf(output_file, " '%c'", s[1]);
1047 } else
1048 fprintf(output_file, " %s", s);
1049 }
1050 if (!rflag)
1051 ++outline;
1052 fprintf(output_file, "\",\n");
1053 }
1054
1055 if (!rflag)
1056 outline += 2;
1057 fprintf(output_file, "};\n#endif\n");
1058 }
1059
1060
1061 void
output_stype(void)1062 output_stype(void)
1063 {
1064 if (!unionized && ntags == 0) {
1065 outline += 3;
1066 fprintf(code_file, "#ifndef YYSTYPE\ntypedef int YYSTYPE;\n#endif\n");
1067 }
1068 }
1069
1070
1071 void
output_trailing_text(void)1072 output_trailing_text(void)
1073 {
1074 int c, last;
1075 FILE *in, *out;
1076
1077 if (line == 0)
1078 return;
1079
1080 in = input_file;
1081 out = code_file;
1082 c = (unsigned char)*cptr;
1083 if (c == '\n') {
1084 ++lineno;
1085 if ((c = getc(in)) == EOF)
1086 return;
1087 if (!lflag) {
1088 ++outline;
1089 fprintf(out, line_format, lineno, input_file_name);
1090 }
1091 if (c == '\n')
1092 ++outline;
1093 putc(c, out);
1094 last = c;
1095 } else {
1096 if (!lflag) {
1097 ++outline;
1098 fprintf(out, line_format, lineno, input_file_name);
1099 }
1100 do {
1101 putc(c, out);
1102 } while ((c = (unsigned char)*++cptr) != '\n');
1103 ++outline;
1104 putc('\n', out);
1105 last = '\n';
1106 }
1107
1108 while ((c = getc(in)) != EOF) {
1109 if (c == '\n')
1110 ++outline;
1111 putc(c, out);
1112 last = c;
1113 }
1114
1115 if (last != '\n') {
1116 ++outline;
1117 putc('\n', out);
1118 }
1119 if (!lflag)
1120 fprintf(out, line_format, ++outline + 1, code_file_name);
1121 }
1122
1123
1124 void
output_semantic_actions(void)1125 output_semantic_actions(void)
1126 {
1127 int c, last;
1128 FILE *out;
1129
1130 rewind(action_file);
1131
1132 if ((c = getc(action_file)) == EOF)
1133 return;
1134
1135 out = code_file;
1136 last = c;
1137 if (c == '\n')
1138 ++outline;
1139 putc(c, out);
1140 while ((c = getc(action_file)) != EOF) {
1141 if (c == '\n')
1142 ++outline;
1143 putc(c, out);
1144 last = c;
1145 }
1146
1147 if (last != '\n') {
1148 ++outline;
1149 putc('\n', out);
1150 }
1151
1152 if (!lflag)
1153 fprintf(out, line_format, ++outline + 1, code_file_name);
1154 }
1155
1156
1157 void
free_itemsets(void)1158 free_itemsets(void)
1159 {
1160 core *cp, *next;
1161
1162 free(state_table);
1163 for (cp = first_state; cp; cp = next) {
1164 next = cp->next;
1165 free(cp);
1166 }
1167 }
1168
1169
1170 void
free_shifts(void)1171 free_shifts(void)
1172 {
1173 shifts *sp, *next;
1174
1175 free(shift_table);
1176 for (sp = first_shift; sp; sp = next) {
1177 next = sp->next;
1178 free(sp);
1179 }
1180 }
1181
1182
1183
1184 void
free_reductions(void)1185 free_reductions(void)
1186 {
1187 reductions *rp, *next;
1188
1189 free(reduction_table);
1190 for (rp = first_reduction; rp; rp = next) {
1191 next = rp->next;
1192 free(rp);
1193 }
1194 }
1195