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