Merge pull request #1591 from akoeplinger/remove-npgsql
[mono.git] / mcs / jay / 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 #include <string.h>
43
44 static int nvectors;
45 static int nentries;
46 static short **froms;
47 static short **tos;
48 static short *tally;
49 static short *width;
50 static short *state_count;
51 static short *order;
52 static short *base;
53 static short *pos;
54 static int maxtable;
55 static short *table;
56 static short *check;
57 static int lowzero;
58 static int high;
59 extern int csharp;
60
61 output () {
62   int lno = 0;
63   char buf [128];
64
65   free_itemsets();
66   free_shifts();
67   free_reductions();
68
69   while (fgets(buf, sizeof buf, stdin) != NULL) {
70     char * cp;
71     ++ lno;
72     if (buf[strlen(buf)-1] != '\n')
73       fprintf(stderr, "jay: line %d is too long\n", lno), done(1);
74     switch (buf[0]) {
75     case '#':   continue;
76     case 't':   if (!tflag) fputs("//t", stdout);
77     case '.':   break;
78     default:
79       cp = strtok(buf, " \t\r\n");
80       if (cp)
81         if (strcmp(cp, "actions") == 0) output_semantic_actions();
82         else if (strcmp(cp, "debug") == 0) output_debug();
83         else if (strcmp(cp, "epilog") == 0) output_trailing_text();
84         else if (strcmp(cp, "prolog") == 0)
85                 output_stored_text(prolog_file, prolog_file_name);
86         else if (strcmp(cp, "local") == 0)
87                 output_stored_text(local_file, local_file_name);
88         else if (strcmp(cp, "tables") == 0)
89           output_rule_data(), output_yydefred(), output_actions();
90         else if (strcmp(cp, "tokens") == 0)
91                 output_defines(strtok(NULL, "\r\n"));
92         else
93           fprintf(stderr, "jay: unknown call (%s) in line %d\n", cp, lno);
94       continue;
95     }
96     fputs(buf+1, stdout), ++ outline;
97   }
98   free_parser();
99 }
100
101 output_rule_data()
102 {
103     register int i;
104     register int j;
105
106         printf("/*\n All more than 3 lines long rules are wrapped into a method\n*/\n");
107
108     for (i = 0; i < nmethods; ++i)
109         {
110                 printf("%s", methods[i]);
111                 FREE(methods[i]);
112                 printf("\n\n");
113         }
114         FREE(methods);
115
116         printf(default_line_format, ++outline + 1);
117
118     printf("  %s static %s short [] yyLhs  = {%16d,",
119            csharp ? "" : " protected",
120            csharp ? "readonly" : "final",
121             symbol_value[start_symbol]);
122
123     j = 10;
124     for (i = 3; i < nrules; i++)
125     {
126         if (j >= 10)
127         {
128             ++outline;
129             putchar('\n');
130             j = 1;
131         }
132         else
133             ++j;
134
135         printf("%5d,", symbol_value[rlhs[i]]);
136     }
137     outline += 2;
138     printf("\n  };\n");
139
140     printf("  %s static %s short [] yyLen = {%12d,",
141            csharp ? "" : "protected",
142            csharp ? "readonly" : "final",
143            2);
144
145     j = 10;
146     for (i = 3; i < nrules; i++)
147     {
148         if (j >= 10)
149         {
150             ++outline;
151             putchar('\n');
152             j = 1;
153         }
154         else
155           j++;
156
157         printf("%5d,", rrhs[i + 1] - rrhs[i] - 1);
158     }
159     outline += 2;
160     printf("\n  };\n");
161 }
162
163
164 output_yydefred()
165 {
166     register int i, j;
167
168     printf("  %s static %s short [] yyDefRed = {%13d,",
169            csharp ? "" : "protected",
170            csharp ? "readonly" : "final",          
171             (defred[0] ? defred[0] - 2 : 0));
172
173     j = 10;
174     for (i = 1; i < nstates; i++)
175     {
176         if (j < 10)
177             ++j;
178         else
179         {
180             ++outline;
181             putchar('\n');
182             j = 1;
183         }
184
185         printf("%5d,", (defred[i] ? defred[i] - 2 : 0));
186     }
187
188     outline += 2;
189     printf("\n  };\n");
190 }
191
192
193 output_actions()
194 {
195     nvectors = 2*nstates + nvars;
196
197     froms = NEW2(nvectors, short *);
198     tos = NEW2(nvectors, short *);
199     tally = NEW2(nvectors, short);
200     width = NEW2(nvectors, short);
201
202     token_actions();
203     FREE(lookaheads);
204     FREE(LA);
205     FREE(LAruleno);
206     FREE(accessing_symbol);
207
208     goto_actions();
209     FREE(goto_map + ntokens);
210     FREE(from_state);
211     FREE(to_state);
212
213     sort_actions();
214     pack_table();
215     output_base();
216     output_table();
217     output_check();
218 }
219
220
221 token_actions()
222 {
223     register int i, j;
224     register int shiftcount, reducecount;
225     register int max, min;
226     register short *actionrow, *r, *s;
227     register action *p;
228
229     actionrow = NEW2(2*ntokens, short);
230     for (i = 0; i < nstates; ++i)
231     {
232         if (parser[i])
233         {
234             for (j = 0; j < 2*ntokens; ++j)
235             actionrow[j] = 0;
236
237             shiftcount = 0;
238             reducecount = 0;
239             for (p = parser[i]; p; p = p->next)
240             {
241                 if (p->suppressed == 0)
242                 {
243                     if (p->action_code == SHIFT)
244                     {
245                         ++shiftcount;
246                         actionrow[p->symbol] = p->number;
247                     }
248                     else if (p->action_code == REDUCE && p->number != defred[i])
249                     {
250                         ++reducecount;
251                         actionrow[p->symbol + ntokens] = p->number;
252                     }
253                 }
254             }
255
256             tally[i] = shiftcount;
257             tally[nstates+i] = reducecount;
258             width[i] = 0;
259             width[nstates+i] = 0;
260             if (shiftcount > 0)
261             {
262                 froms[i] = r = NEW2(shiftcount, short);
263                 tos[i] = s = NEW2(shiftcount, short);
264                 min = MAXSHORT;
265                 max = 0;
266                 for (j = 0; j < ntokens; ++j)
267                 {
268                     if (actionrow[j])
269                     {
270                         if (min > symbol_value[j])
271                             min = symbol_value[j];
272                         if (max < symbol_value[j])
273                             max = symbol_value[j];
274                         *r++ = symbol_value[j];
275                         *s++ = actionrow[j];
276                     }
277                 }
278                 width[i] = max - min + 1;
279             }
280             if (reducecount > 0)
281             {
282                 froms[nstates+i] = r = NEW2(reducecount, short);
283                 tos[nstates+i] = s = NEW2(reducecount, short);
284                 min = MAXSHORT;
285                 max = 0;
286                 for (j = 0; j < ntokens; ++j)
287                 {
288                     if (actionrow[ntokens+j])
289                     {
290                         if (min > symbol_value[j])
291                             min = symbol_value[j];
292                         if (max < symbol_value[j])
293                             max = symbol_value[j];
294                         *r++ = symbol_value[j];
295                         *s++ = actionrow[ntokens+j] - 2;
296                     }
297                 }
298                 width[nstates+i] = max - min + 1;
299             }
300         }
301     }
302     FREE(actionrow);
303 }
304
305 goto_actions()
306 {
307     register int i, j, k;
308
309     state_count = NEW2(nstates, short);
310
311     k = default_goto(start_symbol + 1);
312     printf("  protected static %s short [] yyDgoto  = {%14d,", csharp ? "readonly" : "final", k);
313     save_column(start_symbol + 1, k);
314
315     j = 10;
316     for (i = start_symbol + 2; i < nsyms; i++)
317     {
318         if (j >= 10)
319         {
320             ++outline;
321             putchar('\n');
322             j = 1;
323         }
324         else
325             ++j;
326
327         k = default_goto(i);
328         printf("%5d,", k);
329         save_column(i, k);
330     }
331
332     outline += 2;
333     printf("\n  };\n");
334     FREE(state_count);
335 }
336
337 int
338 default_goto(symbol)
339 int symbol;
340 {
341     register int i;
342     register int m;
343     register int n;
344     register int default_state;
345     register int max;
346
347     m = goto_map[symbol];
348     n = goto_map[symbol + 1];
349
350     if (m == n) return (0);
351
352     for (i = 0; i < nstates; i++)
353         state_count[i] = 0;
354
355     for (i = m; i < n; i++)
356         state_count[to_state[i]]++;
357
358     max = 0;
359     default_state = 0;
360     for (i = 0; i < nstates; i++)
361     {
362         if (state_count[i] > max)
363         {
364             max = state_count[i];
365             default_state = i;
366         }
367     }
368
369     return (default_state);
370 }
371
372
373
374 save_column(symbol, default_state)
375 int symbol;
376 int default_state;
377 {
378     register int i;
379     register int m;
380     register int n;
381     register short *sp;
382     register short *sp1;
383     register short *sp2;
384     register int count;
385     register int symno;
386
387     m = goto_map[symbol];
388     n = goto_map[symbol + 1];
389
390     count = 0;
391     for (i = m; i < n; i++)
392     {
393         if (to_state[i] != default_state)
394             ++count;
395     }
396     if (count == 0) return;
397
398     symno = symbol_value[symbol] + 2*nstates;
399
400     froms[symno] = sp1 = sp = NEW2(count, short);
401     tos[symno] = sp2 = NEW2(count, short);
402
403     for (i = m; i < n; i++)
404     {
405         if (to_state[i] != default_state)
406         {
407             *sp1++ = from_state[i];
408             *sp2++ = to_state[i];
409         }
410     }
411
412     tally[symno] = count;
413     width[symno] = sp1[-1] - sp[0] + 1;
414 }
415
416 sort_actions()
417 {
418   register int i;
419   register int j;
420   register int k;
421   register int t;
422   register int w;
423
424   order = NEW2(nvectors, short);
425   nentries = 0;
426
427   for (i = 0; i < nvectors; i++)
428     {
429       if (tally[i] > 0)
430         {
431           t = tally[i];
432           w = width[i];
433           j = nentries - 1;
434
435           while (j >= 0 && (width[order[j]] < w))
436             j--;
437
438           while (j >= 0 && (width[order[j]] == w) && (tally[order[j]] < t))
439             j--;
440
441           for (k = nentries - 1; k > j; k--)
442             order[k + 1] = order[k];
443
444           order[j + 1] = i;
445           nentries++;
446         }
447     }
448 }
449
450
451 pack_table()
452 {
453     register int i;
454     register int place;
455     register int state;
456
457     base = NEW2(nvectors, short);
458     pos = NEW2(nentries, short);
459
460     maxtable = 1000;
461     table = NEW2(maxtable, short);
462     check = NEW2(maxtable, short);
463
464     lowzero = 0;
465     high = 0;
466
467     for (i = 0; i < maxtable; i++)
468         check[i] = -1;
469
470     for (i = 0; i < nentries; i++)
471     {
472         state = matching_vector(i);
473
474         if (state < 0)
475             place = pack_vector(i);
476         else
477             place = base[state];
478
479         pos[i] = place;
480         base[order[i]] = place;
481     }
482
483     for (i = 0; i < nvectors; i++)
484     {
485         if (froms[i])
486             FREE(froms[i]);
487         if (tos[i])
488             FREE(tos[i]);
489     }
490
491     FREE(froms);
492     FREE(tos);
493     FREE(pos);
494 }
495
496
497 /*  The function matching_vector determines if the vector specified by  */
498 /*  the input parameter matches a previously considered vector.  The    */
499 /*  test at the start of the function checks if the vector represents   */
500 /*  a row of shifts over terminal symbols or a row of reductions, or a  */
501 /*  column of shifts over a nonterminal symbol.  Berkeley Yacc does not */
502 /*  check if a column of shifts over a nonterminal symbols matches a    */
503 /*  previously considered vector.  Because of the nature of LR parsing  */
504 /*  tables, no two columns can match.  Therefore, the only possible     */
505 /*  match would be between a row and a column.  Such matches are        */
506 /*  unlikely.  Therefore, to save time, no attempt is made to see if a  */
507 /*  column matches a previously considered vector.                      */
508 /*                                                                      */
509 /*  Matching_vector is poorly designed.  The test could easily be made  */
510 /*  faster.  Also, it depends on the vectors being in a specific        */
511 /*  order.                                                              */
512
513 int
514 matching_vector(vector)
515 int vector;
516 {
517     register int i;
518     register int j;
519     register int k;
520     register int t;
521     register int w;
522     register int match;
523     register int prev;
524
525     i = order[vector];
526     if (i >= 2*nstates)
527         return (-1);
528
529     t = tally[i];
530     w = width[i];
531
532     for (prev = vector - 1; prev >= 0; prev--)
533     {
534         j = order[prev];
535         if (width[j] != w || tally[j] != t)
536             return (-1);
537
538         match = 1;
539         for (k = 0; match && k < t; k++)
540         {
541             if (tos[j][k] != tos[i][k] || froms[j][k] != froms[i][k])
542                 match = 0;
543         }
544
545         if (match)
546             return (j);
547     }
548
549     return (-1);
550 }
551
552
553
554 int
555 pack_vector(vector)
556 int vector;
557 {
558     register int i, j, k, l;
559     register int t;
560     register int loc;
561     register int ok;
562     register short *from;
563     register short *to;
564     int newmax;
565
566     i = order[vector];
567     t = tally[i];
568     assert(t);
569
570     from = froms[i];
571     to = tos[i];
572
573     j = lowzero - from[0];
574     for (k = 1; k < t; ++k)
575         if (lowzero - from[k] > j)
576             j = lowzero - from[k];
577     for (;; ++j)
578     {
579         if (j == 0)
580             continue;
581         ok = 1;
582         for (k = 0; ok && k < t; k++)
583         {
584             loc = j + from[k];
585             if (loc >= maxtable)
586             {
587                 if (loc >= MAXTABLE)
588                     fatal("maximum table size exceeded");
589
590                 newmax = maxtable;
591                 do { newmax += 200; } while (newmax <= loc);
592                 table = (short *) REALLOC(table, newmax*sizeof(short));
593                 if (table == 0) no_space();
594                 check = (short *) REALLOC(check, newmax*sizeof(short));
595                 if (check == 0) no_space();
596                 for (l  = maxtable; l < newmax; ++l)
597                 {
598                     table[l] = 0;
599                     check[l] = -1;
600                 }
601                 maxtable = newmax;
602             }
603
604             if (check[loc] != -1)
605                 ok = 0;
606         }
607         for (k = 0; ok && k < vector; k++)
608         {
609             if (pos[k] == j)
610                 ok = 0;
611         }
612         if (ok)
613         {
614             for (k = 0; k < t; k++)
615             {
616                 loc = j + from[k];
617                 table[loc] = to[k];
618                 check[loc] = from[k];
619                 if (loc > high) high = loc;
620             }
621
622             while (check[lowzero] != -1)
623                 ++lowzero;
624
625             return (j);
626         }
627     }
628 }
629
630
631
632 output_base()
633 {
634     register int i, j;
635
636     printf("  protected static %s short [] yySindex = {%13d,", csharp? "readonly":"final", base[0]);
637
638     j = 10;
639     for (i = 1; i < nstates; i++)
640     {
641         if (j >= 10)
642         {
643             ++outline;
644             putchar('\n');
645             j = 1;
646         }
647         else
648             ++j;
649
650         printf("%5d,", base[i]);
651     }
652
653     outline += 2;
654     printf("\n  };\n  protected static %s short [] yyRindex = {%13d,",
655            csharp ? "readonly" : "final",
656             base[nstates]);
657
658     j = 10;
659     for (i = nstates + 1; i < 2*nstates; i++)
660     {
661         if (j >= 10)
662         {
663             ++outline;
664             putchar('\n');
665             j = 1;
666         }
667         else
668             ++j;
669
670         printf("%5d,", base[i]);
671     }
672
673     outline += 2;
674     printf("\n  };\n  protected static %s short [] yyGindex = {%13d,",
675            csharp ? "readonly" : "final",
676             base[2*nstates]);
677
678     j = 10;
679     for (i = 2*nstates + 1; i < nvectors - 1; i++)
680     {
681         if (j >= 10)
682         {
683             ++outline;
684             putchar('\n');
685             j = 1;
686         }
687         else
688             ++j;
689
690         printf("%5d,", base[i]);
691     }
692
693     outline += 2;
694     printf("\n  };\n");
695     FREE(base);
696 }
697
698
699
700 output_table()
701 {
702     register int i;
703     register int j;
704
705     printf("  protected static %s short [] yyTable = {%14d,", csharp ? "readonly" : "final", table[0]);
706
707     j = 10;
708     for (i = 1; i <= high; i++)
709     {
710         if (j >= 10)
711         {
712             ++outline;
713             putchar('\n');
714             j = 1;
715         }
716         else
717             ++j;
718
719         printf("%5d,", table[i]);
720     }
721
722     outline += 2;
723     printf("\n  };\n");
724     FREE(table);
725 }
726
727
728
729 output_check()
730 {
731     register int i;
732     register int j;
733
734     printf("  protected static %s short [] yyCheck = {%14d,",
735            csharp ? "readonly" : "final",
736             check[0]);
737
738     j = 10;
739     for (i = 1; i <= high; i++)
740     {
741         if (j >= 10)
742         {
743             ++outline;
744             putchar('\n');
745             j = 1;
746         }
747         else
748             ++j;
749
750         printf("%5d,", check[i]);
751     }
752
753     outline += 2;
754     printf("\n  };\n");
755     FREE(check);
756 }
757
758
759 int
760 is_C_identifier(name)
761 char *name;
762 {
763     register char *s;
764     register int c;
765
766     s = name;
767     c = *s;
768     if (c == '"')
769     {
770         c = *++s;
771         if (!isalpha(c) && c != '_' && c != '$')
772             return (0);
773         while ((c = *++s) != '"')
774         {
775             if (!isalnum(c) && c != '_' && c != '$')
776                 return (0);
777         }
778         return (1);
779     }
780
781     if (!isalpha(c) && c != '_' && c != '$')
782         return (0);
783     while (c = *++s)
784     {
785         if (!isalnum(c) && c != '_' && c != '$')
786             return (0);
787     }
788     return (1);
789 }
790
791
792 output_defines(prefix)
793 char *prefix;
794 {
795     register int c, i;
796     register char *s;
797
798     for (i = 2; i < ntokens; ++i)
799     {
800         s = symbol_name[i];
801         if (is_C_identifier(s))
802         {
803             if (prefix)
804                 printf("  %s ", prefix);
805             c = *s;
806             if (c == '"')
807             {
808                 while ((c = *++s) != '"')
809                 {
810                     putchar(c);
811                 }
812             }
813             else
814             {
815                 do
816                 {
817                     putchar(c);
818                 }
819                 while (c = *++s);
820             }
821             ++outline;
822             printf(" = %d%s\n", symbol_value[i], csharp ? ";" : ";");
823         }
824     }
825
826     ++outline;
827     printf("  %s yyErrorCode = %d%s\n", prefix ? prefix : "", symbol_value[1], csharp ? ";" : ";");
828 }
829
830
831 output_stored_text(file, name)
832 FILE *file;
833 char *name;
834 {
835     register int c;
836     register FILE *in;
837
838     fflush(file);
839     in = fopen(name, "r");
840     if (in == NULL)
841         open_error(name);
842     if ((c = getc(in)) != EOF) {
843       if (c ==  '\n')
844         ++outline;
845       putchar(c);
846       while ((c = getc(in)) != EOF)
847       {
848         if (c == '\n')
849             ++outline;
850         putchar(c);
851       }
852       printf(default_line_format, ++outline + 1);
853     }
854     fclose(in);
855 }
856
857
858 output_debug()
859 {
860     register int i, j, k, max;
861     char **symnam, *s;
862     char * prefix = tflag ? "" : "//t";
863
864     ++outline;
865     printf("  protected %s int yyFinal = %d;\n", csharp ? "const" : "static final", final_state);
866
867       ++outline;
868           printf ("%s // Put this array into a separate class so it is only initialized if debugging is actually used\n", prefix);
869           printf ("%s // Use MarshalByRefObject to disable inlining\n", prefix);
870           printf("%s class YYRules %s {\n", prefix, csharp ? ": MarshalByRefObject" : "");
871       printf("%s  public static %s string [] yyRule = {\n", prefix, csharp ? "readonly" : "final");
872       for (i = 2; i < nrules; ++i)
873       {
874           printf("%s    \"%s :", prefix, symbol_name[rlhs[i]]);
875           for (j = rrhs[i]; ritem[j] > 0; ++j)
876           {
877               s = symbol_name[ritem[j]];
878               if (s[0] == '"')
879               {
880                   printf(" \\\"");
881                   while (*++s != '"')
882                   {
883                       if (*s == '\\')
884                       {
885                           if (s[1] == '\\')
886                               printf("\\\\\\\\");
887                           else
888                               printf("\\\\%c", s[1]);
889                           ++s;
890                       }
891                       else
892                           putchar(*s);
893                   }
894                   printf("\\\"");
895               }
896               else if (s[0] == '\'')
897               {
898                   if (s[1] == '"')
899                       printf(" '\\\"'");
900                   else if (s[1] == '\\')
901                   {
902                       if (s[2] == '\\')
903                           printf(" '\\\\\\\\");
904                       else
905                           printf(" '\\\\%c", s[2]);
906                       s += 2;
907                       while (*++s != '\'')
908                           putchar(*s);
909                       putchar('\'');
910                   }
911                   else
912                       printf(" '%c'", s[1]);
913               }
914               else
915                   printf(" %s", s);
916           }
917           ++outline;
918           printf("\",\n");
919       }
920       ++ outline;
921       printf("%s  };\n", prefix);
922           printf ("%s public static string getRule (int index) {\n", prefix);
923           printf ("%s    return yyRule [index];\n", prefix);
924           printf ("%s }\n", prefix);
925           printf ("%s}\n", prefix);
926
927     max = 0;
928     for (i = 2; i < ntokens; ++i)
929         if (symbol_value[i] > max)
930             max = symbol_value[i];
931
932         /* need yyNames for yyExpecting() */
933
934       printf("  protected static %s string [] yyNames = {", csharp ? "readonly" : "final");
935       symnam = (char **) MALLOC((max+1)*sizeof(char *));
936       if (symnam == 0) no_space();
937   
938       /* Note that it is  not necessary to initialize the element       */
939       /* symnam[max].                                                   */
940       for (i = 0; i < max; ++i)
941           symnam[i] = 0;
942       for (i = ntokens - 1; i >= 2; --i)
943           symnam[symbol_value[i]] = symbol_name[i];
944       symnam[0] = "end-of-file";
945   
946       j = 70; fputs("    ", stdout);
947       for (i = 0; i <= max; ++i)
948       {
949           if (s = symnam[i])
950           {
951               if (s[0] == '"')
952               {
953                   k = 7;
954                   while (*++s != '"')
955                   {
956                       ++k;
957                       if (*s == '\\')
958                       {
959                           k += 2;
960                           if (*++s == '\\')
961                               ++k;
962                       }
963                   }
964                   j += k;
965                   if (j > 70)
966                   {
967                       ++outline;
968                       printf("\n    ");
969                       j = k;
970                   }
971                   printf("\"\\\"");
972                   s = symnam[i];
973                   while (*++s != '"')
974                   {
975                       if (*s == '\\')
976                       {
977                           printf("\\\\");
978                           if (*++s == '\\')
979                               printf("\\\\");
980                           else
981                               putchar(*s);
982                       }
983                       else
984                           putchar(*s);
985                   }
986                   printf("\\\"\",");
987               }
988               else if (s[0] == '\'')
989               {
990                   if (s[1] == '"')
991                   {
992                       j += 7;
993                       if (j > 70)
994                       {
995                           ++outline;
996                           printf("\n    ");
997                           j = 7;
998                       }
999                       printf("\"'\\\"'\",");
1000                   }
1001                   else
1002                   {
1003                       k = 5;
1004                       while (*++s != '\'')
1005                       {
1006                           ++k;
1007                           if (*s == '\\')
1008                           {
1009                               k += 2;
1010                               if (*++s == '\\')
1011                                   ++k;
1012                           }
1013                       }
1014                       j += k;
1015                       if (j > 70)
1016                       {
1017                           ++outline;
1018                           printf("\n    ");
1019                           j = k;
1020                       }
1021                       printf("\"'");
1022                       s = symnam[i];
1023                       while (*++s != '\'')
1024                       {
1025                           if (*s == '\\')
1026                           {
1027                               printf("\\\\");
1028                               if (*++s == '\\')
1029                                   printf("\\\\");
1030                               else
1031                                   putchar(*s);
1032                           }
1033                           else
1034                               putchar(*s);
1035                       }
1036                       printf("'\",");
1037                   }
1038               }
1039               else
1040               {
1041                   k = strlen(s) + 3;
1042                   j += k;
1043                   if (j > 70)
1044                   {
1045                       ++outline;
1046                       printf("\n    ");
1047                       j = k;
1048                   }
1049                   putchar('"');
1050                   do { putchar(*s); } while (*++s);
1051                   printf("\",");
1052               }
1053           }
1054           else
1055           {
1056               j += 5;
1057               if (j > 70)
1058               {
1059                   ++outline;
1060                   printf("\n    ");
1061                   j = 5;
1062               }
1063               printf("null,");
1064           }
1065       }
1066       outline += 2;
1067       printf("\n  };\n");
1068       FREE(symnam);
1069 }
1070
1071 output_trailing_text()
1072 {
1073     register int c, last;
1074     register FILE *in;
1075
1076     if (line == 0)
1077         return;
1078
1079     in = input_file;
1080     c = *cptr;
1081     if (c == '\n')
1082     {
1083         ++lineno;
1084         if ((c = getc(in)) == EOF)
1085             return;
1086         ++outline;
1087         printf(line_format, lineno, input_file_name);
1088         if (c == '\n')
1089             ++outline;
1090         putchar(c);
1091         last = c;
1092     }
1093     else
1094     {
1095         ++outline;
1096         printf(line_format, lineno, input_file_name);
1097         do { putchar(c); } while ((c = *++cptr) != '\n');
1098         ++outline;
1099         putchar('\n');
1100         last = '\n';
1101     }
1102
1103     while ((c = getc(in)) != EOF)
1104     {
1105         if (c == '\n')
1106             ++outline;
1107         putchar(c);
1108         last = c;
1109     }
1110
1111     if (last != '\n')
1112     {
1113         ++outline;
1114         putchar('\n');
1115     }
1116     printf(default_line_format, ++outline + 1);
1117 }
1118
1119
1120 output_semantic_actions()
1121 {
1122     register int c, last;
1123
1124     fclose(action_file);
1125     action_file = fopen(action_file_name, "r");
1126     if (action_file == NULL)
1127         open_error(action_file_name);
1128
1129     if ((c = getc(action_file)) == EOF)
1130         return;
1131
1132     last = c;
1133     if (c == '\n')
1134         ++outline;
1135     putchar(c);
1136     while ((c = getc(action_file)) != EOF)
1137     {
1138         if (c == '\n')
1139             ++outline;
1140         putchar(c);
1141         last = c;
1142     }
1143
1144     if (last != '\n')
1145     {
1146         ++outline;
1147         putchar('\n');
1148     }
1149
1150     printf(default_line_format, ++outline + 1);
1151 }
1152
1153
1154 free_itemsets()
1155 {
1156     register core *cp, *next;
1157
1158     FREE(state_table);
1159     for (cp = first_state; cp; cp = next)
1160     {
1161         next = cp->next;
1162         FREE(cp);
1163     }
1164 }
1165
1166
1167 free_shifts()
1168 {
1169     register shifts *sp, *next;
1170
1171     FREE(shift_table);
1172     for (sp = first_shift; sp; sp = next)
1173     {
1174         next = sp->next;
1175         FREE(sp);
1176     }
1177 }
1178
1179
1180
1181 free_reductions()
1182 {
1183     register reductions *rp, *next;
1184
1185     FREE(reduction_table);
1186     for (rp = first_reduction; rp; rp = next)
1187     {
1188         next = rp->next;
1189         FREE(rp);
1190     }
1191 }