Annotation of src/usr.bin/yacc/output.c, Revision 1.17
1.17 ! millert 1: /* $OpenBSD: output.c,v 1.16 2012/03/03 19:15:00 nicm Exp $ */
1.2 deraadt 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.
1.10 millert 19: * 3. Neither the name of the University nor the names of its contributors
1.2 deraadt 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: */
1.1 deraadt 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:
1.8 millert 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);
1.1 deraadt 79:
1.6 pvalchev 80: void
1.11 pvalchev 81: output(void)
1.1 deraadt 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) write_section(tables);
96: write_section(header);
97: output_trailing_text();
98: write_section(body);
99: output_semantic_actions();
100: write_section(trailer);
101: }
102:
103:
1.6 pvalchev 104: void
1.11 pvalchev 105: output_prefix(void)
1.1 deraadt 106: {
107: if (symbol_prefix == NULL)
108: symbol_prefix = "yy";
109: else
110: {
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;
1.4 deraadt 132: fprintf(code_file, "#define yysslim %ssslim\n", symbol_prefix);
133: ++outline;
1.1 deraadt 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);
1.4 deraadt 139: ++outline;
140: fprintf(code_file, "#define yystacksize %sstacksize\n", symbol_prefix);
1.1 deraadt 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:
1.6 pvalchev 169: void
1.11 pvalchev 170: output_rule_data(void)
1.1 deraadt 171: {
1.7 mpech 172: int i;
173: int j;
1.1 deraadt 174:
1.9 mickey 175: fprintf(output_file,
176: "#if defined(__cplusplus) || defined(__STDC__)\n"
177: "const short %slhs[] =\n"
178: "#else\n"
179: "short %slhs[] =\n"
180: "#endif\n"
181: "\t{%42d,", symbol_prefix, symbol_prefix, symbol_value[start_symbol]);
1.1 deraadt 182:
183: j = 10;
184: for (i = 3; i < nrules; i++)
185: {
186: if (j >= 10)
187: {
188: if (!rflag) ++outline;
189: putc('\n', output_file);
190: j = 1;
191: }
192: else
193: ++j;
194:
195: fprintf(output_file, "%5d,", symbol_value[rlhs[i]]);
196: }
197: if (!rflag) outline += 2;
198: fprintf(output_file, "\n};\n");
199:
1.9 mickey 200: fprintf(output_file,
201: "#if defined(__cplusplus) || defined(__STDC__)\n"
202: "const short %slen[] =\n"
203: "#else\n"
204: "short %slen[] =\n"
205: "#endif\n"
206: "\t{%42d,", symbol_prefix, symbol_prefix, 2);
1.1 deraadt 207:
208: j = 10;
209: for (i = 3; i < nrules; i++)
210: {
211: if (j >= 10)
212: {
213: if (!rflag) ++outline;
214: putc('\n', output_file);
215: j = 1;
216: }
217: else
218: j++;
219:
220: fprintf(output_file, "%5d,", rrhs[i + 1] - rrhs[i] - 1);
221: }
222: if (!rflag) outline += 2;
223: fprintf(output_file, "\n};\n");
224: }
225:
226:
1.6 pvalchev 227: void
1.11 pvalchev 228: output_yydefred(void)
1.1 deraadt 229: {
1.7 mpech 230: int i, j;
1.1 deraadt 231:
1.9 mickey 232: fprintf(output_file,
233: "#if defined(__cplusplus) || defined(__STDC__)\n"
234: "const short %sdefred[] =\n"
235: "#else\n"
236: "short %sdefred[] =\n"
237: "#endif\n"
238: "\t{%39d,",
239: symbol_prefix, symbol_prefix, (defred[0] ? defred[0] - 2 : 0));
1.1 deraadt 240:
241: j = 10;
242: for (i = 1; i < nstates; i++)
243: {
244: if (j < 10)
245: ++j;
246: else
247: {
248: if (!rflag) ++outline;
249: putc('\n', output_file);
250: j = 1;
251: }
252:
253: fprintf(output_file, "%5d,", (defred[i] ? defred[i] - 2 : 0));
254: }
255:
256: if (!rflag) outline += 2;
257: fprintf(output_file, "\n};\n");
258: }
259:
260:
1.6 pvalchev 261: void
1.11 pvalchev 262: output_actions(void)
1.1 deraadt 263: {
264: nvectors = 2*nstates + nvars;
265:
266: froms = NEW2(nvectors, short *);
267: tos = NEW2(nvectors, short *);
268: tally = NEW2(nvectors, short);
269: width = NEW2(nvectors, short);
270:
271: token_actions();
1.17 ! millert 272: free(lookaheads);
! 273: free(LA);
! 274: free(LAruleno);
! 275: free(accessing_symbol);
1.1 deraadt 276:
277: goto_actions();
1.17 ! millert 278: free(goto_map + ntokens);
! 279: free(from_state);
! 280: free(to_state);
1.1 deraadt 281:
282: sort_actions();
283: pack_table();
284: output_base();
285: output_table();
286: output_check();
287: }
288:
289:
1.6 pvalchev 290: void
1.11 pvalchev 291: token_actions(void)
1.1 deraadt 292: {
1.7 mpech 293: int i, j;
294: int shiftcount, reducecount;
295: int max, min;
296: short *actionrow, *r, *s;
297: action *p;
1.1 deraadt 298:
299: actionrow = NEW2(2*ntokens, short);
300: for (i = 0; i < nstates; ++i)
301: {
302: if (parser[i])
303: {
304: for (j = 0; j < 2*ntokens; ++j)
305: actionrow[j] = 0;
306:
307: shiftcount = 0;
308: reducecount = 0;
309: for (p = parser[i]; p; p = p->next)
310: {
311: if (p->suppressed == 0)
312: {
313: if (p->action_code == SHIFT)
314: {
315: ++shiftcount;
316: actionrow[p->symbol] = p->number;
317: }
318: else if (p->action_code == REDUCE && p->number != defred[i])
319: {
320: ++reducecount;
321: actionrow[p->symbol + ntokens] = p->number;
322: }
323: }
324: }
325:
326: tally[i] = shiftcount;
327: tally[nstates+i] = reducecount;
328: width[i] = 0;
329: width[nstates+i] = 0;
330: if (shiftcount > 0)
331: {
332: froms[i] = r = NEW2(shiftcount, short);
333: tos[i] = s = NEW2(shiftcount, short);
334: min = MAXSHORT;
335: max = 0;
336: for (j = 0; j < ntokens; ++j)
337: {
338: if (actionrow[j])
339: {
340: if (min > symbol_value[j])
341: min = symbol_value[j];
342: if (max < symbol_value[j])
343: max = symbol_value[j];
344: *r++ = symbol_value[j];
345: *s++ = actionrow[j];
346: }
347: }
348: width[i] = max - min + 1;
349: }
350: if (reducecount > 0)
351: {
352: froms[nstates+i] = r = NEW2(reducecount, short);
353: tos[nstates+i] = s = NEW2(reducecount, short);
354: min = MAXSHORT;
355: max = 0;
356: for (j = 0; j < ntokens; ++j)
357: {
358: if (actionrow[ntokens+j])
359: {
360: if (min > symbol_value[j])
361: min = symbol_value[j];
362: if (max < symbol_value[j])
363: max = symbol_value[j];
364: *r++ = symbol_value[j];
365: *s++ = actionrow[ntokens+j] - 2;
366: }
367: }
368: width[nstates+i] = max - min + 1;
369: }
370: }
371: }
1.17 ! millert 372: free(actionrow);
1.1 deraadt 373: }
374:
1.6 pvalchev 375: void
1.11 pvalchev 376: goto_actions(void)
1.1 deraadt 377: {
1.7 mpech 378: int i, j, k;
1.1 deraadt 379:
380: state_count = NEW2(nstates, short);
381:
382: k = default_goto(start_symbol + 1);
1.9 mickey 383: fprintf(output_file,
384: "#if defined(__cplusplus) || defined(__STDC__)\n"
385: "const short %sdgoto[] =\n"
386: "#else\n"
387: "short %sdgoto[] =\n"
388: "#endif\n"
389: "\t{%40d,", symbol_prefix, symbol_prefix, k);
1.1 deraadt 390: save_column(start_symbol + 1, k);
391:
392: j = 10;
393: for (i = start_symbol + 2; i < nsyms; i++)
394: {
395: if (j >= 10)
396: {
397: if (!rflag) ++outline;
398: putc('\n', output_file);
399: j = 1;
400: }
401: else
402: ++j;
403:
404: k = default_goto(i);
405: fprintf(output_file, "%5d,", k);
406: save_column(i, k);
407: }
408:
409: if (!rflag) outline += 2;
410: fprintf(output_file, "\n};\n");
1.17 ! millert 411: free(state_count);
1.1 deraadt 412: }
413:
414: int
1.11 pvalchev 415: default_goto(int symbol)
1.1 deraadt 416: {
1.7 mpech 417: int i;
418: int m;
419: int n;
420: int default_state;
421: int max;
1.1 deraadt 422:
423: m = goto_map[symbol];
424: n = goto_map[symbol + 1];
425:
426: if (m == n) return (0);
427:
1.16 nicm 428: memset(state_count, 0, nstates * sizeof(short));
1.1 deraadt 429:
430: for (i = m; i < n; i++)
431: state_count[to_state[i]]++;
432:
433: max = 0;
434: default_state = 0;
435: for (i = 0; i < nstates; i++)
436: {
437: if (state_count[i] > max)
438: {
439: max = state_count[i];
440: default_state = i;
441: }
442: }
443:
444: return (default_state);
445: }
446:
447:
448:
1.6 pvalchev 449: void
1.11 pvalchev 450: save_column(int symbol, int default_state)
1.1 deraadt 451: {
1.7 mpech 452: int i;
453: int m;
454: int n;
455: short *sp;
456: short *sp1;
457: short *sp2;
458: int count;
459: int symno;
1.1 deraadt 460:
461: m = goto_map[symbol];
462: n = goto_map[symbol + 1];
463:
464: count = 0;
465: for (i = m; i < n; i++)
466: {
467: if (to_state[i] != default_state)
468: ++count;
469: }
470: if (count == 0) return;
471:
472: symno = symbol_value[symbol] + 2*nstates;
473:
474: froms[symno] = sp1 = sp = NEW2(count, short);
475: tos[symno] = sp2 = NEW2(count, short);
476:
477: for (i = m; i < n; i++)
478: {
479: if (to_state[i] != default_state)
480: {
481: *sp1++ = from_state[i];
482: *sp2++ = to_state[i];
483: }
484: }
485:
486: tally[symno] = count;
487: width[symno] = sp1[-1] - sp[0] + 1;
488: }
489:
1.6 pvalchev 490: void
1.11 pvalchev 491: sort_actions(void)
1.1 deraadt 492: {
1.7 mpech 493: int i;
494: int j;
495: int k;
496: int t;
497: int w;
1.1 deraadt 498:
499: order = NEW2(nvectors, short);
500: nentries = 0;
501:
502: for (i = 0; i < nvectors; i++)
503: {
504: if (tally[i] > 0)
505: {
506: t = tally[i];
507: w = width[i];
508: j = nentries - 1;
509:
510: while (j >= 0 && (width[order[j]] < w))
511: j--;
512:
513: while (j >= 0 && (width[order[j]] == w) && (tally[order[j]] < t))
514: j--;
515:
516: for (k = nentries - 1; k > j; k--)
517: order[k + 1] = order[k];
518:
519: order[j + 1] = i;
520: nentries++;
521: }
522: }
523: }
524:
525:
1.6 pvalchev 526: void
1.11 pvalchev 527: pack_table(void)
1.1 deraadt 528: {
1.7 mpech 529: int i;
530: int place;
531: int state;
1.1 deraadt 532:
533: base = NEW2(nvectors, short);
534: pos = NEW2(nentries, short);
535:
536: maxtable = 1000;
537: table = NEW2(maxtable, short);
538: check = NEW2(maxtable, short);
539:
540: lowzero = 0;
541: high = 0;
542:
543: for (i = 0; i < maxtable; i++)
544: check[i] = -1;
545:
546: for (i = 0; i < nentries; i++)
547: {
548: state = matching_vector(i);
549:
550: if (state < 0)
551: place = pack_vector(i);
552: else
553: place = base[state];
554:
555: pos[i] = place;
556: base[order[i]] = place;
557: }
558:
559: for (i = 0; i < nvectors; i++)
560: {
561: if (froms[i])
1.17 ! millert 562: free(froms[i]);
1.1 deraadt 563: if (tos[i])
1.17 ! millert 564: free(tos[i]);
1.1 deraadt 565: }
566:
1.17 ! millert 567: free(froms);
! 568: free(tos);
! 569: free(pos);
1.1 deraadt 570: }
571:
572:
573: /* The function matching_vector determines if the vector specified by */
574: /* the input parameter matches a previously considered vector. The */
575: /* test at the start of the function checks if the vector represents */
576: /* a row of shifts over terminal symbols or a row of reductions, or a */
577: /* column of shifts over a nonterminal symbol. Berkeley Yacc does not */
578: /* check if a column of shifts over a nonterminal symbols matches a */
579: /* previously considered vector. Because of the nature of LR parsing */
580: /* tables, no two columns can match. Therefore, the only possible */
581: /* match would be between a row and a column. Such matches are */
582: /* unlikely. Therefore, to save time, no attempt is made to see if a */
583: /* column matches a previously considered vector. */
584: /* */
585: /* Matching_vector is poorly designed. The test could easily be made */
586: /* faster. Also, it depends on the vectors being in a specific */
587: /* order. */
588:
589: int
1.11 pvalchev 590: matching_vector(int vector)
1.1 deraadt 591: {
1.7 mpech 592: int i;
593: int j;
594: int k;
595: int t;
596: int w;
597: int match;
598: int prev;
1.1 deraadt 599:
600: i = order[vector];
601: if (i >= 2*nstates)
602: return (-1);
603:
604: t = tally[i];
605: w = width[i];
606:
607: for (prev = vector - 1; prev >= 0; prev--)
608: {
609: j = order[prev];
610: if (width[j] != w || tally[j] != t)
611: return (-1);
612:
613: match = 1;
614: for (k = 0; match && k < t; k++)
615: {
616: if (tos[j][k] != tos[i][k] || froms[j][k] != froms[i][k])
617: match = 0;
618: }
619:
620: if (match)
621: return (j);
622: }
623:
624: return (-1);
625: }
626:
627:
628:
629: int
1.11 pvalchev 630: pack_vector(int vector)
1.1 deraadt 631: {
1.7 mpech 632: int i, j, k, l;
633: int t;
634: int loc;
635: int ok;
636: short *from;
637: short *to;
1.1 deraadt 638: int newmax;
639:
640: i = order[vector];
641: t = tally[i];
642: assert(t);
643:
644: from = froms[i];
645: to = tos[i];
646:
647: j = lowzero - from[0];
648: for (k = 1; k < t; ++k)
649: if (lowzero - from[k] > j)
650: j = lowzero - from[k];
651: for (;; ++j)
652: {
653: if (j == 0)
654: continue;
655: ok = 1;
656: for (k = 0; ok && k < t; k++)
657: {
658: loc = j + from[k];
659: if (loc >= maxtable)
660: {
661: if (loc >= MAXTABLE)
662: fatal("maximum table size exceeded");
663:
664: newmax = maxtable;
665: do { newmax += 200; } while (newmax <= loc);
1.17 ! millert 666: table = (short *) realloc(table, newmax*sizeof(short));
1.1 deraadt 667: if (table == 0) no_space();
1.17 ! millert 668: check = (short *) realloc(check, newmax*sizeof(short));
1.1 deraadt 669: if (check == 0) no_space();
670: for (l = maxtable; l < newmax; ++l)
671: {
672: table[l] = 0;
673: check[l] = -1;
674: }
675: maxtable = newmax;
676: }
677:
678: if (check[loc] != -1)
679: ok = 0;
680: }
681: for (k = 0; ok && k < vector; k++)
682: {
683: if (pos[k] == j)
684: ok = 0;
685: }
686: if (ok)
687: {
688: for (k = 0; k < t; k++)
689: {
690: loc = j + from[k];
691: table[loc] = to[k];
692: check[loc] = from[k];
693: if (loc > high) high = loc;
694: }
695:
696: while (check[lowzero] != -1)
697: ++lowzero;
698:
699: return (j);
700: }
701: }
702: }
703:
704:
705:
1.6 pvalchev 706: void
1.11 pvalchev 707: output_base(void)
1.1 deraadt 708: {
1.7 mpech 709: int i, j;
1.1 deraadt 710:
1.9 mickey 711: fprintf(output_file,
712: "#if defined(__cplusplus) || defined(__STDC__)\n"
713: "const short %ssindex[] =\n"
714: "#else\n"
715: "short %ssindex[] =\n"
716: "#endif\n"
717: "\t{%39d,", symbol_prefix, symbol_prefix, base[0]);
1.1 deraadt 718:
719: j = 10;
720: for (i = 1; i < nstates; i++)
721: {
722: if (j >= 10)
723: {
724: if (!rflag) ++outline;
725: putc('\n', output_file);
726: j = 1;
727: }
728: else
729: ++j;
730:
731: fprintf(output_file, "%5d,", base[i]);
732: }
733:
734: if (!rflag) outline += 2;
1.9 mickey 735: fprintf(output_file,
736: "};\n"
737: "#if defined(__cplusplus) || defined(__STDC__)\n"
738: "const short %srindex[] =\n"
739: "#else\n"
740: "short %srindex[] =\n"
741: "#endif\n"
742: "\t{%39d,", symbol_prefix, symbol_prefix, base[nstates]);
1.1 deraadt 743:
744: j = 10;
745: for (i = nstates + 1; i < 2*nstates; i++)
746: {
747: if (j >= 10)
748: {
749: if (!rflag) ++outline;
750: putc('\n', output_file);
751: j = 1;
752: }
753: else
754: ++j;
755:
756: fprintf(output_file, "%5d,", base[i]);
757: }
758:
759: if (!rflag) outline += 2;
1.9 mickey 760: fprintf(output_file,
761: "};\n"
762: "#if defined(__cplusplus) || defined(__STDC__)\n"
763: "const short %sgindex[] =\n"
764: "#else\n"
765: "short %sgindex[] =\n"
766: "#endif\n"
767: "\t{%39d,", symbol_prefix, symbol_prefix, base[2*nstates]);
1.1 deraadt 768:
769: j = 10;
770: for (i = 2*nstates + 1; i < nvectors - 1; i++)
771: {
772: if (j >= 10)
773: {
774: if (!rflag) ++outline;
775: putc('\n', output_file);
776: j = 1;
777: }
778: else
779: ++j;
780:
781: fprintf(output_file, "%5d,", base[i]);
782: }
783:
784: if (!rflag) outline += 2;
785: fprintf(output_file, "\n};\n");
1.17 ! millert 786: free(base);
1.1 deraadt 787: }
788:
789:
1.6 pvalchev 790: void
1.11 pvalchev 791: output_table(void)
1.1 deraadt 792: {
1.7 mpech 793: int i;
794: int j;
1.1 deraadt 795:
796: ++outline;
797: fprintf(code_file, "#define YYTABLESIZE %d\n", high);
1.9 mickey 798: fprintf(output_file,
799: "#if defined(__cplusplus) || defined(__STDC__)\n"
800: "const short %stable[] =\n"
801: "#else\n"
802: "short %stable[] =\n"
803: "#endif\n"
804: "\t{%40d,", symbol_prefix, symbol_prefix, table[0]);
1.1 deraadt 805:
806: j = 10;
807: for (i = 1; i <= high; i++)
808: {
809: if (j >= 10)
810: {
811: if (!rflag) ++outline;
812: putc('\n', output_file);
813: j = 1;
814: }
815: else
816: ++j;
817:
818: fprintf(output_file, "%5d,", table[i]);
819: }
820:
821: if (!rflag) outline += 2;
822: fprintf(output_file, "\n};\n");
1.17 ! millert 823: free(table);
1.1 deraadt 824: }
825:
826:
1.6 pvalchev 827: void
1.11 pvalchev 828: output_check(void)
1.1 deraadt 829: {
1.7 mpech 830: int i;
831: int j;
1.1 deraadt 832:
1.9 mickey 833: fprintf(output_file,
834: "#if defined(__cplusplus) || defined(__STDC__)\n"
835: "const short %scheck[] =\n"
836: "#else\n"
837: "short %scheck[] =\n"
838: "#endif\n"
839: "\t{%40d,", symbol_prefix, symbol_prefix, check[0]);
1.1 deraadt 840:
841: j = 10;
842: for (i = 1; i <= high; i++)
843: {
844: if (j >= 10)
845: {
846: if (!rflag) ++outline;
847: putc('\n', output_file);
848: j = 1;
849: }
850: else
851: ++j;
852:
853: fprintf(output_file, "%5d,", check[i]);
854: }
855:
856: if (!rflag) outline += 2;
857: fprintf(output_file, "\n};\n");
1.17 ! millert 858: free(check);
1.1 deraadt 859: }
860:
861:
862: int
1.11 pvalchev 863: is_C_identifier(char *name)
1.1 deraadt 864: {
1.7 mpech 865: char *s;
866: int c;
1.1 deraadt 867:
868: s = name;
869: c = *s;
870: if (c == '"')
871: {
872: c = *++s;
873: if (!isalpha(c) && c != '_' && c != '$')
874: return (0);
875: while ((c = *++s) != '"')
876: {
877: if (!isalnum(c) && c != '_' && c != '$')
878: return (0);
879: }
880: return (1);
881: }
882:
883: if (!isalpha(c) && c != '_' && c != '$')
884: return (0);
1.14 pvalchev 885: while ((c = *++s))
1.1 deraadt 886: {
887: if (!isalnum(c) && c != '_' && c != '$')
888: return (0);
889: }
890: return (1);
891: }
892:
893:
1.6 pvalchev 894: void
1.11 pvalchev 895: output_defines(void)
1.1 deraadt 896: {
1.7 mpech 897: int c, i;
898: char *s;
1.1 deraadt 899:
900: for (i = 2; i < ntokens; ++i)
901: {
902: s = symbol_name[i];
903: if (is_C_identifier(s))
904: {
905: fprintf(code_file, "#define ");
906: if (dflag) fprintf(defines_file, "#define ");
907: c = *s;
908: if (c == '"')
909: {
910: while ((c = *++s) != '"')
911: {
912: putc(c, code_file);
913: if (dflag) putc(c, defines_file);
914: }
915: }
916: else
917: {
918: do
919: {
920: putc(c, code_file);
921: if (dflag) putc(c, defines_file);
922: }
1.14 pvalchev 923: while ((c = *++s));
1.1 deraadt 924: }
925: ++outline;
926: fprintf(code_file, " %d\n", symbol_value[i]);
927: if (dflag) fprintf(defines_file, " %d\n", symbol_value[i]);
928: }
929: }
930:
931: ++outline;
932: fprintf(code_file, "#define YYERRCODE %d\n", symbol_value[1]);
933:
934: if (dflag && unionized)
935: {
936: fclose(union_file);
937: union_file = fopen(union_file_name, "r");
938: if (union_file == NULL) open_error(union_file_name);
939: while ((c = getc(union_file)) != EOF)
940: putc(c, defines_file);
1.12 deraadt 941: fprintf(defines_file, " YYSTYPE;\n");
942: fprintf(defines_file, "#endif /* YYSTYPE_DEFINED */\n");
943: fprintf(defines_file, "extern YYSTYPE %slval;\n",
1.1 deraadt 944: symbol_prefix);
945: }
946: }
947:
948:
1.6 pvalchev 949: void
1.11 pvalchev 950: output_stored_text(void)
1.1 deraadt 951: {
1.7 mpech 952: int c;
953: FILE *in, *out;
1.1 deraadt 954:
955: fclose(text_file);
956: text_file = fopen(text_file_name, "r");
957: if (text_file == NULL)
958: open_error(text_file_name);
959: in = text_file;
960: if ((c = getc(in)) == EOF)
961: return;
962: out = code_file;
963: if (c == '\n')
964: ++outline;
965: putc(c, out);
966: while ((c = getc(in)) != EOF)
967: {
968: if (c == '\n')
969: ++outline;
970: putc(c, out);
971: }
972: if (!lflag)
973: fprintf(out, line_format, ++outline + 1, code_file_name);
974: }
975:
976:
1.6 pvalchev 977: void
1.11 pvalchev 978: output_debug(void)
1.1 deraadt 979: {
1.7 mpech 980: int i, j, k, max;
1.1 deraadt 981: char **symnam, *s;
982:
983: ++outline;
984: fprintf(code_file, "#define YYFINAL %d\n", final_state);
985: outline += 3;
986: fprintf(code_file, "#ifndef YYDEBUG\n#define YYDEBUG %d\n#endif\n",
987: tflag);
988: if (rflag)
989: fprintf(output_file, "#ifndef YYDEBUG\n#define YYDEBUG %d\n#endif\n",
990: tflag);
991:
992: max = 0;
993: for (i = 2; i < ntokens; ++i)
994: if (symbol_value[i] > max)
995: max = symbol_value[i];
996: ++outline;
997: fprintf(code_file, "#define YYMAXTOKEN %d\n", max);
998:
1.17 ! millert 999: symnam = (char **) malloc((max+1)*sizeof(char *));
1.1 deraadt 1000: if (symnam == 0) no_space();
1001:
1002: /* Note that it is not necessary to initialize the element */
1003: /* symnam[max]. */
1.16 nicm 1004: memset(symnam, 0, max * sizeof(char *));
1.1 deraadt 1005: for (i = ntokens - 1; i >= 2; --i)
1006: symnam[symbol_value[i]] = symbol_name[i];
1007: symnam[0] = "end-of-file";
1008:
1009: if (!rflag) ++outline;
1.9 mickey 1010: fprintf(output_file,
1011: "#if YYDEBUG\n"
1012: "#if defined(__cplusplus) || defined(__STDC__)\n"
1013: "const char * const %sname[] =\n"
1014: "#else\n"
1015: "char *%sname[] =\n"
1016: "#endif\n"
1017: "\t{", symbol_prefix, symbol_prefix);
1.1 deraadt 1018: j = 80;
1019: for (i = 0; i <= max; ++i)
1020: {
1.6 pvalchev 1021: if ((s = symnam[i]) != '\0')
1.1 deraadt 1022: {
1023: if (s[0] == '"')
1024: {
1025: k = 7;
1026: while (*++s != '"')
1027: {
1028: ++k;
1029: if (*s == '\\')
1030: {
1031: k += 2;
1032: if (*++s == '\\')
1033: ++k;
1034: }
1035: }
1036: j += k;
1037: if (j > 80)
1038: {
1039: if (!rflag) ++outline;
1040: putc('\n', output_file);
1041: j = k;
1042: }
1043: fprintf(output_file, "\"\\\"");
1044: s = symnam[i];
1045: while (*++s != '"')
1046: {
1047: if (*s == '\\')
1048: {
1049: fprintf(output_file, "\\\\");
1050: if (*++s == '\\')
1051: fprintf(output_file, "\\\\");
1052: else
1053: putc(*s, output_file);
1054: }
1055: else
1056: putc(*s, output_file);
1057: }
1058: fprintf(output_file, "\\\"\",");
1059: }
1060: else if (s[0] == '\'')
1061: {
1062: if (s[1] == '"')
1063: {
1064: j += 7;
1065: if (j > 80)
1066: {
1067: if (!rflag) ++outline;
1068: putc('\n', output_file);
1069: j = 7;
1070: }
1071: fprintf(output_file, "\"'\\\"'\",");
1072: }
1073: else
1074: {
1075: k = 5;
1076: while (*++s != '\'')
1077: {
1078: ++k;
1079: if (*s == '\\')
1080: {
1081: k += 2;
1082: if (*++s == '\\')
1083: ++k;
1084: }
1085: }
1086: j += k;
1087: if (j > 80)
1088: {
1089: if (!rflag) ++outline;
1090: putc('\n', output_file);
1091: j = k;
1092: }
1093: fprintf(output_file, "\"'");
1094: s = symnam[i];
1095: while (*++s != '\'')
1096: {
1097: if (*s == '\\')
1098: {
1099: fprintf(output_file, "\\\\");
1100: if (*++s == '\\')
1101: fprintf(output_file, "\\\\");
1102: else
1103: putc(*s, output_file);
1104: }
1105: else
1106: putc(*s, output_file);
1107: }
1108: fprintf(output_file, "'\",");
1109: }
1110: }
1111: else
1112: {
1113: k = strlen(s) + 3;
1114: j += k;
1115: if (j > 80)
1116: {
1117: if (!rflag) ++outline;
1118: putc('\n', output_file);
1119: j = k;
1120: }
1121: putc('"', output_file);
1122: do { putc(*s, output_file); } while (*++s);
1123: fprintf(output_file, "\",");
1124: }
1125: }
1126: else
1127: {
1128: j += 2;
1129: if (j > 80)
1130: {
1131: if (!rflag) ++outline;
1132: putc('\n', output_file);
1133: j = 2;
1134: }
1135: fprintf(output_file, "0,");
1136: }
1137: }
1138: if (!rflag) outline += 2;
1139: fprintf(output_file, "\n};\n");
1.17 ! millert 1140: free(symnam);
1.1 deraadt 1141:
1142: if (!rflag) ++outline;
1.9 mickey 1143: fprintf(output_file,
1144: "#if defined(__cplusplus) || defined(__STDC__)\n"
1145: "const char * const %srule[] =\n"
1146: "#else\n"
1147: "char *%srule[] =\n"
1148: "#endif\n"
1149: "\t{", symbol_prefix, symbol_prefix);
1.1 deraadt 1150: for (i = 2; i < nrules; ++i)
1151: {
1152: fprintf(output_file, "\"%s :", symbol_name[rlhs[i]]);
1153: for (j = rrhs[i]; ritem[j] > 0; ++j)
1154: {
1155: s = symbol_name[ritem[j]];
1156: if (s[0] == '"')
1157: {
1158: fprintf(output_file, " \\\"");
1159: while (*++s != '"')
1160: {
1161: if (*s == '\\')
1162: {
1163: if (s[1] == '\\')
1164: fprintf(output_file, "\\\\\\\\");
1165: else
1166: fprintf(output_file, "\\\\%c", s[1]);
1167: ++s;
1168: }
1169: else
1170: putc(*s, output_file);
1171: }
1172: fprintf(output_file, "\\\"");
1173: }
1174: else if (s[0] == '\'')
1175: {
1176: if (s[1] == '"')
1177: fprintf(output_file, " '\\\"'");
1178: else if (s[1] == '\\')
1179: {
1180: if (s[2] == '\\')
1181: fprintf(output_file, " '\\\\\\\\");
1182: else
1183: fprintf(output_file, " '\\\\%c", s[2]);
1184: s += 2;
1185: while (*++s != '\'')
1186: putc(*s, output_file);
1187: putc('\'', output_file);
1188: }
1189: else
1190: fprintf(output_file, " '%c'", s[1]);
1191: }
1192: else
1193: fprintf(output_file, " %s", s);
1194: }
1195: if (!rflag) ++outline;
1196: fprintf(output_file, "\",\n");
1197: }
1198:
1199: if (!rflag) outline += 2;
1200: fprintf(output_file, "};\n#endif\n");
1201: }
1202:
1203:
1.6 pvalchev 1204: void
1.11 pvalchev 1205: output_stype(void)
1.1 deraadt 1206: {
1207: if (!unionized && ntags == 0)
1208: {
1209: outline += 3;
1210: fprintf(code_file, "#ifndef YYSTYPE\ntypedef int YYSTYPE;\n#endif\n");
1211: }
1212: }
1213:
1214:
1.6 pvalchev 1215: void
1.11 pvalchev 1216: output_trailing_text(void)
1.1 deraadt 1217: {
1.7 mpech 1218: int c, last;
1219: FILE *in, *out;
1.1 deraadt 1220:
1221: if (line == 0)
1222: return;
1223:
1224: in = input_file;
1225: out = code_file;
1226: c = *cptr;
1227: if (c == '\n')
1228: {
1229: ++lineno;
1230: if ((c = getc(in)) == EOF)
1231: return;
1232: if (!lflag)
1233: {
1234: ++outline;
1235: fprintf(out, line_format, lineno, input_file_name);
1236: }
1237: if (c == '\n')
1238: ++outline;
1239: putc(c, out);
1240: last = c;
1241: }
1242: else
1243: {
1244: if (!lflag)
1245: {
1246: ++outline;
1247: fprintf(out, line_format, lineno, input_file_name);
1248: }
1249: do { putc(c, out); } while ((c = *++cptr) != '\n');
1250: ++outline;
1251: putc('\n', out);
1252: last = '\n';
1253: }
1254:
1255: while ((c = getc(in)) != EOF)
1256: {
1257: if (c == '\n')
1258: ++outline;
1259: putc(c, out);
1260: last = c;
1261: }
1262:
1263: if (last != '\n')
1264: {
1265: ++outline;
1266: putc('\n', out);
1267: }
1268: if (!lflag)
1269: fprintf(out, line_format, ++outline + 1, code_file_name);
1270: }
1271:
1272:
1.6 pvalchev 1273: void
1.11 pvalchev 1274: output_semantic_actions(void)
1.1 deraadt 1275: {
1.7 mpech 1276: int c, last;
1277: FILE *out;
1.1 deraadt 1278:
1279: fclose(action_file);
1280: action_file = fopen(action_file_name, "r");
1281: if (action_file == NULL)
1282: open_error(action_file_name);
1283:
1284: if ((c = getc(action_file)) == EOF)
1285: return;
1286:
1287: out = code_file;
1288: last = c;
1289: if (c == '\n')
1290: ++outline;
1291: putc(c, out);
1292: while ((c = getc(action_file)) != EOF)
1293: {
1294: if (c == '\n')
1295: ++outline;
1296: putc(c, out);
1297: last = c;
1298: }
1299:
1300: if (last != '\n')
1301: {
1302: ++outline;
1303: putc('\n', out);
1304: }
1305:
1306: if (!lflag)
1307: fprintf(out, line_format, ++outline + 1, code_file_name);
1308: }
1309:
1310:
1.6 pvalchev 1311: void
1.11 pvalchev 1312: free_itemsets(void)
1.1 deraadt 1313: {
1.7 mpech 1314: core *cp, *next;
1.1 deraadt 1315:
1.17 ! millert 1316: free(state_table);
1.1 deraadt 1317: for (cp = first_state; cp; cp = next)
1318: {
1319: next = cp->next;
1.17 ! millert 1320: free(cp);
1.1 deraadt 1321: }
1322: }
1323:
1324:
1.6 pvalchev 1325: void
1.11 pvalchev 1326: free_shifts(void)
1.1 deraadt 1327: {
1.7 mpech 1328: shifts *sp, *next;
1.1 deraadt 1329:
1.17 ! millert 1330: free(shift_table);
1.1 deraadt 1331: for (sp = first_shift; sp; sp = next)
1332: {
1333: next = sp->next;
1.17 ! millert 1334: free(sp);
1.1 deraadt 1335: }
1336: }
1337:
1338:
1339:
1.6 pvalchev 1340: void
1.11 pvalchev 1341: free_reductions(void)
1.1 deraadt 1342: {
1.7 mpech 1343: reductions *rp, *next;
1.1 deraadt 1344:
1.17 ! millert 1345: free(reduction_table);
1.1 deraadt 1346: for (rp = first_reduction; rp; rp = next)
1347: {
1348: next = rp->next;
1.17 ! millert 1349: free(rp);
1.1 deraadt 1350: }
1351: }