1 /* $NetBSD: output.c,v 1.10 2013/12/30 19:08:55 christos Exp $ */ 2 3 /* Id: output.c,v 1.45 2013/03/05 00:29:17 tom Exp */ 4 5 #include "defs.h" 6 7 #include <sys/cdefs.h> 8 __RCSID("$NetBSD: output.c,v 1.10 2013/12/30 19:08:55 christos Exp $"); 9 10 #define StaticOrR (rflag ? "" : "static ") 11 #define CountLine(fp) (!rflag || ((fp) == code_file)) 12 13 static int nvectors; 14 static int nentries; 15 static Value_t **froms; 16 static Value_t **tos; 17 static Value_t *tally; 18 static Value_t *width; 19 static Value_t *state_count; 20 static Value_t *order; 21 static Value_t *base; 22 static Value_t *pos; 23 static int maxtable; 24 static Value_t *table; 25 static Value_t *check; 26 static int lowzero; 27 static int high; 28 29 static void 30 putc_code(FILE * fp, int c) 31 { 32 if ((c == '\n') && (fp == code_file)) 33 ++outline; 34 putc(c, fp); 35 } 36 37 static void 38 putl_code(FILE * fp, const char *s) 39 { 40 if (fp == code_file) 41 ++outline; 42 fputs(s, fp); 43 } 44 45 static void 46 puts_code(FILE * fp, const char *s) 47 { 48 fputs(s, fp); 49 } 50 51 static void 52 write_code_lineno(FILE * fp) 53 { 54 if (!lflag && (fp == code_file)) 55 { 56 ++outline; 57 fprintf(fp, line_format, outline, code_file_name); 58 } 59 } 60 61 static void 62 write_input_lineno(void) 63 { 64 if (!lflag) 65 { 66 ++outline; 67 fprintf(code_file, line_format, lineno, input_file_name); 68 } 69 } 70 71 static void 72 define_prefixed(FILE * fp, const char *name) 73 { 74 int bump_line = CountLine(fp); 75 if (bump_line) 76 ++outline; 77 fprintf(fp, "\n"); 78 79 if (bump_line) 80 ++outline; 81 fprintf(fp, "#ifndef %s\n", name); 82 83 if (bump_line) 84 ++outline; 85 fprintf(fp, "#define %-10s %s%s\n", name, symbol_prefix, name + 2); 86 87 if (bump_line) 88 ++outline; 89 fprintf(fp, "#endif /* %s */\n", name); 90 } 91 92 static void 93 output_prefix(FILE * fp) 94 { 95 if (symbol_prefix == NULL) 96 { 97 symbol_prefix = "yy"; 98 } 99 else 100 { 101 define_prefixed(fp, "yyparse"); 102 define_prefixed(fp, "yylex"); 103 define_prefixed(fp, "yyerror"); 104 define_prefixed(fp, "yychar"); 105 define_prefixed(fp, "yyval"); 106 define_prefixed(fp, "yylval"); 107 define_prefixed(fp, "yydebug"); 108 define_prefixed(fp, "yynerrs"); 109 define_prefixed(fp, "yyerrflag"); 110 define_prefixed(fp, "yylhs"); 111 define_prefixed(fp, "yylen"); 112 define_prefixed(fp, "yydefred"); 113 define_prefixed(fp, "yydgoto"); 114 define_prefixed(fp, "yysindex"); 115 define_prefixed(fp, "yyrindex"); 116 define_prefixed(fp, "yygindex"); 117 define_prefixed(fp, "yytable"); 118 define_prefixed(fp, "yycheck"); 119 define_prefixed(fp, "yytname"); 120 define_prefixed(fp, "yyrule"); 121 } 122 if (CountLine(fp)) 123 ++outline; 124 fprintf(fp, "#define YYPREFIX \"%s\"\n", symbol_prefix); 125 } 126 127 static void 128 output_newline(void) 129 { 130 if (!rflag) 131 ++outline; 132 putc('\n', output_file); 133 } 134 135 static void 136 output_line(const char *value) 137 { 138 fputs(value, output_file); 139 output_newline(); 140 } 141 142 static void 143 output_int(int value) 144 { 145 fprintf(output_file, "%5d,", value); 146 } 147 148 static void 149 start_int_table(const char *name, int value) 150 { 151 int need = 34 - (int)(strlen(symbol_prefix) + strlen(name)); 152 153 if (need < 6) 154 need = 6; 155 fprintf(output_file, 156 "%sconst short %s%s[] = {%*d,", 157 StaticOrR, symbol_prefix, name, need, value); 158 } 159 160 static void 161 start_str_table(const char *name) 162 { 163 fprintf(output_file, 164 "%sconst char *%s%s[] = {", 165 StaticOrR, "yy", name); 166 output_newline(); 167 } 168 169 static void 170 end_table(void) 171 { 172 output_newline(); 173 output_line("};"); 174 } 175 176 static void 177 output_rule_data(void) 178 { 179 int i; 180 int j; 181 182 start_int_table("lhs", symbol_value[start_symbol]); 183 184 j = 10; 185 for (i = 3; i < nrules; i++) 186 { 187 if (j >= 10) 188 { 189 output_newline(); 190 j = 1; 191 } 192 else 193 ++j; 194 195 output_int(symbol_value[rlhs[i]]); 196 } 197 end_table(); 198 199 start_int_table("len", 2); 200 201 j = 10; 202 for (i = 3; i < nrules; i++) 203 { 204 if (j >= 10) 205 { 206 output_newline(); 207 j = 1; 208 } 209 else 210 j++; 211 212 output_int(rrhs[i + 1] - rrhs[i] - 1); 213 } 214 end_table(); 215 } 216 217 static void 218 output_yydefred(void) 219 { 220 int i, j; 221 222 start_int_table("defred", (defred[0] ? defred[0] - 2 : 0)); 223 224 j = 10; 225 for (i = 1; i < nstates; i++) 226 { 227 if (j < 10) 228 ++j; 229 else 230 { 231 output_newline(); 232 j = 1; 233 } 234 235 output_int((defred[i] ? defred[i] - 2 : 0)); 236 } 237 238 end_table(); 239 } 240 241 static void 242 token_actions(void) 243 { 244 int i, j; 245 Value_t shiftcount, reducecount; 246 int max, min; 247 Value_t *actionrow, *r, *s; 248 action *p; 249 250 actionrow = NEW2(2 * ntokens, Value_t); 251 for (i = 0; i < nstates; ++i) 252 { 253 if (parser[i]) 254 { 255 for (j = 0; j < 2 * ntokens; ++j) 256 actionrow[j] = 0; 257 258 shiftcount = 0; 259 reducecount = 0; 260 for (p = parser[i]; p; p = p->next) 261 { 262 if (p->suppressed == 0) 263 { 264 if (p->action_code == SHIFT) 265 { 266 ++shiftcount; 267 actionrow[p->symbol] = p->number; 268 } 269 else if (p->action_code == REDUCE && p->number != defred[i]) 270 { 271 ++reducecount; 272 actionrow[p->symbol + ntokens] = p->number; 273 } 274 } 275 } 276 277 tally[i] = shiftcount; 278 tally[nstates + i] = reducecount; 279 width[i] = 0; 280 width[nstates + i] = 0; 281 if (shiftcount > 0) 282 { 283 froms[i] = r = NEW2(shiftcount, Value_t); 284 tos[i] = s = NEW2(shiftcount, Value_t); 285 min = MAXSHORT; 286 max = 0; 287 for (j = 0; j < ntokens; ++j) 288 { 289 if (actionrow[j]) 290 { 291 if (min > symbol_value[j]) 292 min = symbol_value[j]; 293 if (max < symbol_value[j]) 294 max = symbol_value[j]; 295 *r++ = symbol_value[j]; 296 *s++ = actionrow[j]; 297 } 298 } 299 width[i] = (Value_t) (max - min + 1); 300 } 301 if (reducecount > 0) 302 { 303 froms[nstates + i] = r = NEW2(reducecount, Value_t); 304 tos[nstates + i] = s = NEW2(reducecount, Value_t); 305 min = MAXSHORT; 306 max = 0; 307 for (j = 0; j < ntokens; ++j) 308 { 309 if (actionrow[ntokens + j]) 310 { 311 if (min > symbol_value[j]) 312 min = symbol_value[j]; 313 if (max < symbol_value[j]) 314 max = symbol_value[j]; 315 *r++ = symbol_value[j]; 316 *s++ = (Value_t) (actionrow[ntokens + j] - 2); 317 } 318 } 319 width[nstates + i] = (Value_t) (max - min + 1); 320 } 321 } 322 } 323 FREE(actionrow); 324 } 325 326 static int 327 default_goto(int symbol) 328 { 329 int i; 330 int m; 331 int n; 332 int default_state; 333 int max; 334 335 m = goto_map[symbol]; 336 n = goto_map[symbol + 1]; 337 338 if (m == n) 339 return (0); 340 341 for (i = 0; i < nstates; i++) 342 state_count[i] = 0; 343 344 for (i = m; i < n; i++) 345 state_count[to_state[i]]++; 346 347 max = 0; 348 default_state = 0; 349 for (i = 0; i < nstates; i++) 350 { 351 if (state_count[i] > max) 352 { 353 max = state_count[i]; 354 default_state = i; 355 } 356 } 357 358 return (default_state); 359 } 360 361 static void 362 save_column(int symbol, int default_state) 363 { 364 int i; 365 int m; 366 int n; 367 Value_t *sp; 368 Value_t *sp1; 369 Value_t *sp2; 370 Value_t count; 371 int symno; 372 373 m = goto_map[symbol]; 374 n = goto_map[symbol + 1]; 375 376 count = 0; 377 for (i = m; i < n; i++) 378 { 379 if (to_state[i] != default_state) 380 ++count; 381 } 382 if (count == 0) 383 return; 384 385 symno = symbol_value[symbol] + 2 * nstates; 386 387 froms[symno] = sp1 = sp = NEW2(count, Value_t); 388 tos[symno] = sp2 = NEW2(count, Value_t); 389 390 for (i = m; i < n; i++) 391 { 392 if (to_state[i] != default_state) 393 { 394 *sp1++ = from_state[i]; 395 *sp2++ = to_state[i]; 396 } 397 } 398 399 tally[symno] = count; 400 width[symno] = (Value_t) (sp1[-1] - sp[0] + 1); 401 } 402 403 static void 404 goto_actions(void) 405 { 406 int i, j, k; 407 408 state_count = NEW2(nstates, Value_t); 409 410 k = default_goto(start_symbol + 1); 411 start_int_table("dgoto", k); 412 save_column(start_symbol + 1, k); 413 414 j = 10; 415 for (i = start_symbol + 2; i < nsyms; i++) 416 { 417 if (j >= 10) 418 { 419 output_newline(); 420 j = 1; 421 } 422 else 423 ++j; 424 425 k = default_goto(i); 426 output_int(k); 427 save_column(i, k); 428 } 429 430 end_table(); 431 FREE(state_count); 432 } 433 434 static void 435 sort_actions(void) 436 { 437 Value_t i; 438 int j; 439 int k; 440 int t; 441 int w; 442 443 order = NEW2(nvectors, Value_t); 444 nentries = 0; 445 446 for (i = 0; i < nvectors; i++) 447 { 448 if (tally[i] > 0) 449 { 450 t = tally[i]; 451 w = width[i]; 452 j = nentries - 1; 453 454 while (j >= 0 && (width[order[j]] < w)) 455 j--; 456 457 while (j >= 0 && (width[order[j]] == w) && (tally[order[j]] < t)) 458 j--; 459 460 for (k = nentries - 1; k > j; k--) 461 order[k + 1] = order[k]; 462 463 order[j + 1] = i; 464 nentries++; 465 } 466 } 467 } 468 469 /* The function matching_vector determines if the vector specified by */ 470 /* the input parameter matches a previously considered vector. The */ 471 /* test at the start of the function checks if the vector represents */ 472 /* a row of shifts over terminal symbols or a row of reductions, or a */ 473 /* column of shifts over a nonterminal symbol. Berkeley Yacc does not */ 474 /* check if a column of shifts over a nonterminal symbols matches a */ 475 /* previously considered vector. Because of the nature of LR parsing */ 476 /* tables, no two columns can match. Therefore, the only possible */ 477 /* match would be between a row and a column. Such matches are */ 478 /* unlikely. Therefore, to save time, no attempt is made to see if a */ 479 /* column matches a previously considered vector. */ 480 /* */ 481 /* Matching_vector is poorly designed. The test could easily be made */ 482 /* faster. Also, it depends on the vectors being in a specific */ 483 /* order. */ 484 485 static int 486 matching_vector(int vector) 487 { 488 int i; 489 int j; 490 int k; 491 int t; 492 int w; 493 int match; 494 int prev; 495 496 i = order[vector]; 497 if (i >= 2 * nstates) 498 return (-1); 499 500 t = tally[i]; 501 w = width[i]; 502 503 for (prev = vector - 1; prev >= 0; prev--) 504 { 505 j = order[prev]; 506 if (width[j] != w || tally[j] != t) 507 return (-1); 508 509 match = 1; 510 for (k = 0; match && k < t; k++) 511 { 512 if (tos[j][k] != tos[i][k] || froms[j][k] != froms[i][k]) 513 match = 0; 514 } 515 516 if (match) 517 return (j); 518 } 519 520 return (-1); 521 } 522 523 static int 524 pack_vector(int vector) 525 { 526 int i, j, k, l; 527 int t; 528 int loc; 529 int ok; 530 Value_t *from; 531 Value_t *to; 532 int newmax; 533 534 i = order[vector]; 535 t = tally[i]; 536 assert(t); 537 538 from = froms[i]; 539 to = tos[i]; 540 541 j = lowzero - from[0]; 542 for (k = 1; k < t; ++k) 543 if (lowzero - from[k] > j) 544 j = lowzero - from[k]; 545 for (;; ++j) 546 { 547 if (j == 0) 548 continue; 549 ok = 1; 550 for (k = 0; ok && k < t; k++) 551 { 552 loc = j + from[k]; 553 if (loc >= maxtable - 1) 554 { 555 if (loc >= MAXTABLE - 1) 556 fatal("maximum table size exceeded"); 557 558 newmax = maxtable; 559 do 560 { 561 newmax += 200; 562 } 563 while (newmax <= loc); 564 565 table = TREALLOC(Value_t, table, newmax); 566 NO_SPACE(table); 567 568 check = TREALLOC(Value_t, check, newmax); 569 NO_SPACE(check); 570 571 for (l = maxtable; l < newmax; ++l) 572 { 573 table[l] = 0; 574 check[l] = -1; 575 } 576 maxtable = newmax; 577 } 578 579 if (check[loc] != -1) 580 ok = 0; 581 } 582 for (k = 0; ok && k < vector; k++) 583 { 584 if (pos[k] == j) 585 ok = 0; 586 } 587 if (ok) 588 { 589 for (k = 0; k < t; k++) 590 { 591 loc = j + from[k]; 592 table[loc] = to[k]; 593 check[loc] = from[k]; 594 if (loc > high) 595 high = loc; 596 } 597 598 while (check[lowzero] != -1) 599 ++lowzero; 600 601 return (j); 602 } 603 } 604 } 605 606 static void 607 pack_table(void) 608 { 609 int i; 610 Value_t place; 611 int state; 612 613 base = NEW2(nvectors, Value_t); 614 pos = NEW2(nentries, Value_t); 615 616 maxtable = 1000; 617 table = NEW2(maxtable, Value_t); 618 check = NEW2(maxtable, Value_t); 619 620 lowzero = 0; 621 high = 0; 622 623 for (i = 0; i < maxtable; i++) 624 check[i] = -1; 625 626 for (i = 0; i < nentries; i++) 627 { 628 state = matching_vector(i); 629 630 if (state < 0) 631 place = (Value_t) pack_vector(i); 632 else 633 place = base[state]; 634 635 pos[i] = place; 636 base[order[i]] = place; 637 } 638 639 for (i = 0; i < nvectors; i++) 640 { 641 if (froms[i]) 642 FREE(froms[i]); 643 if (tos[i]) 644 FREE(tos[i]); 645 } 646 647 FREE(froms); 648 FREE(tos); 649 FREE(pos); 650 } 651 652 static void 653 output_base(void) 654 { 655 int i, j; 656 657 start_int_table("sindex", base[0]); 658 659 j = 10; 660 for (i = 1; i < nstates; i++) 661 { 662 if (j >= 10) 663 { 664 output_newline(); 665 j = 1; 666 } 667 else 668 ++j; 669 670 output_int(base[i]); 671 } 672 673 end_table(); 674 675 start_int_table("rindex", base[nstates]); 676 677 j = 10; 678 for (i = nstates + 1; i < 2 * nstates; i++) 679 { 680 if (j >= 10) 681 { 682 output_newline(); 683 j = 1; 684 } 685 else 686 ++j; 687 688 output_int(base[i]); 689 } 690 691 end_table(); 692 693 start_int_table("gindex", base[2 * nstates]); 694 695 j = 10; 696 for (i = 2 * nstates + 1; i < nvectors - 1; i++) 697 { 698 if (j >= 10) 699 { 700 output_newline(); 701 j = 1; 702 } 703 else 704 ++j; 705 706 output_int(base[i]); 707 } 708 709 end_table(); 710 FREE(base); 711 } 712 713 static void 714 output_table(void) 715 { 716 int i; 717 int j; 718 719 ++outline; 720 fprintf(code_file, "#define YYTABLESIZE %d\n", high); 721 start_int_table("table", table[0]); 722 723 j = 10; 724 for (i = 1; i <= high; i++) 725 { 726 if (j >= 10) 727 { 728 output_newline(); 729 j = 1; 730 } 731 else 732 ++j; 733 734 output_int(table[i]); 735 } 736 737 end_table(); 738 FREE(table); 739 } 740 741 static void 742 output_check(void) 743 { 744 int i; 745 int j; 746 747 start_int_table("check", check[0]); 748 749 j = 10; 750 for (i = 1; i <= high; i++) 751 { 752 if (j >= 10) 753 { 754 output_newline(); 755 j = 1; 756 } 757 else 758 ++j; 759 760 output_int(check[i]); 761 } 762 763 end_table(); 764 FREE(check); 765 } 766 767 static void 768 output_actions(void) 769 { 770 nvectors = 2 * nstates + nvars; 771 772 froms = NEW2(nvectors, Value_t *); 773 tos = NEW2(nvectors, Value_t *); 774 tally = NEW2(nvectors, Value_t); 775 width = NEW2(nvectors, Value_t); 776 777 token_actions(); 778 FREE(lookaheads); 779 FREE(LA); 780 FREE(LAruleno); 781 FREE(accessing_symbol); 782 783 goto_actions(); 784 FREE(goto_map + ntokens); 785 FREE(from_state); 786 FREE(to_state); 787 788 sort_actions(); 789 pack_table(); 790 output_base(); 791 output_table(); 792 output_check(); 793 } 794 795 static int 796 is_C_identifier(char *name) 797 { 798 char *s; 799 int c; 800 801 s = name; 802 c = *s; 803 if (c == '"') 804 { 805 c = *++s; 806 if (!isalpha(c) && c != '_' && c != '$') 807 return (0); 808 while ((c = *++s) != '"') 809 { 810 if (!isalnum(c) && c != '_' && c != '$') 811 return (0); 812 } 813 return (1); 814 } 815 816 if (!isalpha(c) && c != '_' && c != '$') 817 return (0); 818 while ((c = *++s) != 0) 819 { 820 if (!isalnum(c) && c != '_' && c != '$') 821 return (0); 822 } 823 return (1); 824 } 825 826 static void 827 output_defines(FILE * fp) 828 { 829 int c, i; 830 char *s; 831 832 for (i = 2; i < ntokens; ++i) 833 { 834 s = symbol_name[i]; 835 if (is_C_identifier(s) && (!sflag || *s != '"')) 836 { 837 fprintf(fp, "#define "); 838 c = *s; 839 if (c == '"') 840 { 841 while ((c = *++s) != '"') 842 { 843 putc(c, fp); 844 } 845 } 846 else 847 { 848 do 849 { 850 putc(c, fp); 851 } 852 while ((c = *++s) != 0); 853 } 854 if (fp == code_file) 855 ++outline; 856 fprintf(fp, " %d\n", symbol_value[i]); 857 } 858 } 859 860 if (fp == code_file) 861 ++outline; 862 if (fp != defines_file || iflag) 863 fprintf(fp, "#define YYERRCODE %d\n", symbol_value[1]); 864 865 if (fp == defines_file || (iflag && !dflag)) 866 { 867 if (unionized) 868 { 869 if (union_file != 0) 870 { 871 rewind(union_file); 872 while ((c = getc(union_file)) != EOF) 873 putc(c, fp); 874 } 875 fprintf(fp, "extern YYSTYPE %slval;\n", symbol_prefix); 876 } 877 } 878 } 879 880 static void 881 output_stored_text(FILE * fp) 882 { 883 int c; 884 FILE *in; 885 886 rewind(text_file); 887 if (text_file == NULL) 888 open_error("text_file"); 889 in = text_file; 890 if ((c = getc(in)) == EOF) 891 return; 892 putc_code(fp, c); 893 while ((c = getc(in)) != EOF) 894 { 895 putc_code(fp, c); 896 } 897 write_code_lineno(fp); 898 } 899 900 static void 901 output_debug(void) 902 { 903 int i, j, k, max; 904 const char **symnam; 905 const char *s; 906 907 ++outline; 908 fprintf(code_file, "#define YYFINAL %d\n", final_state); 909 910 putl_code(code_file, "#ifndef YYDEBUG\n"); 911 ++outline; 912 fprintf(code_file, "#define YYDEBUG %d\n", tflag); 913 putl_code(code_file, "#endif\n"); 914 915 if (rflag) 916 { 917 fprintf(output_file, "#ifndef YYDEBUG\n"); 918 fprintf(output_file, "#define YYDEBUG %d\n", tflag); 919 fprintf(output_file, "#endif\n"); 920 } 921 922 max = 0; 923 for (i = 2; i < ntokens; ++i) 924 if (symbol_value[i] > max) 925 max = symbol_value[i]; 926 927 ++outline; 928 fprintf(code_file, "#define YYMAXTOKEN %d\n", max); 929 fprintf(code_file, "#define YYTRANSLATE(a) ((a) > YYMAXTOKEN ? " 930 "(YYMAXTOKEN + 1) : (a))\n"); 931 932 symnam = TMALLOC(const char *, max + 2); 933 NO_SPACE(symnam); 934 935 /* Note that it is not necessary to initialize the element */ 936 /* symnam[max]. */ 937 for (i = 0; i <= max; ++i) 938 symnam[i] = 0; 939 for (i = ntokens - 1; i >= 2; --i) 940 symnam[symbol_value[i]] = symbol_name[i]; 941 symnam[0] = "end-of-file"; 942 symnam[max + 1] = "illegal-token"; 943 944 if (!token_table) 945 output_line("#if YYDEBUG"); 946 947 start_str_table("tname"); 948 j = 80; 949 for (i = 0; i <= max + 1; ++i) 950 { 951 if ((s = symnam[i]) != 0) 952 { 953 if (s[0] == '"') 954 { 955 k = 7; 956 while (*++s != '"') 957 { 958 ++k; 959 if (*s == '\\') 960 { 961 k += 2; 962 if (*++s == '\\') 963 ++k; 964 } 965 } 966 j += k; 967 if (j > 80) 968 { 969 output_newline(); 970 j = k; 971 } 972 fprintf(output_file, "\"\\\""); 973 s = symnam[i]; 974 while (*++s != '"') 975 { 976 if (*s == '\\') 977 { 978 fprintf(output_file, "\\\\"); 979 if (*++s == '\\') 980 fprintf(output_file, "\\\\"); 981 else 982 putc(*s, output_file); 983 } 984 else 985 putc(*s, output_file); 986 } 987 fprintf(output_file, "\\\"\","); 988 } 989 else if (s[0] == '\'') 990 { 991 if (s[1] == '"') 992 { 993 j += 7; 994 if (j > 80) 995 { 996 output_newline(); 997 j = 7; 998 } 999 fprintf(output_file, "\"'\\\"'\","); 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 > 80) 1016 { 1017 output_newline(); 1018 j = k; 1019 } 1020 fprintf(output_file, "\"'"); 1021 s = symnam[i]; 1022 while (*++s != '\'') 1023 { 1024 if (*s == '\\') 1025 { 1026 fprintf(output_file, "\\\\"); 1027 if (*++s == '\\') 1028 fprintf(output_file, "\\\\"); 1029 else 1030 putc(*s, output_file); 1031 } 1032 else 1033 putc(*s, output_file); 1034 } 1035 fprintf(output_file, "'\","); 1036 } 1037 } 1038 else 1039 { 1040 k = (int)strlen(s) + 3; 1041 j += k; 1042 if (j > 80) 1043 { 1044 output_newline(); 1045 j = k; 1046 } 1047 putc('"', output_file); 1048 do 1049 { 1050 putc(*s, output_file); 1051 } 1052 while (*++s); 1053 fprintf(output_file, "\","); 1054 } 1055 } 1056 else 1057 { 1058 j += 2; 1059 if (j > 80) 1060 { 1061 output_newline(); 1062 j = 2; 1063 } 1064 fprintf(output_file, "0,"); 1065 } 1066 } 1067 end_table(); 1068 FREE(symnam); 1069 1070 if (token_table) 1071 output_line("#if YYDEBUG"); 1072 start_str_table("rule"); 1073 for (i = 2; i < nrules; ++i) 1074 { 1075 fprintf(output_file, "\"%s :", symbol_name[rlhs[i]]); 1076 for (j = rrhs[i]; ritem[j] > 0; ++j) 1077 { 1078 s = symbol_name[ritem[j]]; 1079 if (s[0] == '"') 1080 { 1081 fprintf(output_file, " \\\""); 1082 while (*++s != '"') 1083 { 1084 if (*s == '\\') 1085 { 1086 if (s[1] == '\\') 1087 fprintf(output_file, "\\\\\\\\"); 1088 else 1089 fprintf(output_file, "\\\\%c", s[1]); 1090 ++s; 1091 } 1092 else 1093 putc(*s, output_file); 1094 } 1095 fprintf(output_file, "\\\""); 1096 } 1097 else if (s[0] == '\'') 1098 { 1099 if (s[1] == '"') 1100 fprintf(output_file, " '\\\"'"); 1101 else if (s[1] == '\\') 1102 { 1103 if (s[2] == '\\') 1104 fprintf(output_file, " '\\\\\\\\"); 1105 else 1106 fprintf(output_file, " '\\\\%c", s[2]); 1107 s += 2; 1108 while (*++s != '\'') 1109 putc(*s, output_file); 1110 putc('\'', output_file); 1111 } 1112 else 1113 fprintf(output_file, " '%c'", s[1]); 1114 } 1115 else 1116 fprintf(output_file, " %s", s); 1117 } 1118 fprintf(output_file, "\","); 1119 output_newline(); 1120 } 1121 1122 end_table(); 1123 output_line("#endif"); 1124 } 1125 1126 static void 1127 output_pure_parser(FILE * fp) 1128 { 1129 putc_code(fp, '\n'); 1130 1131 if (fp == code_file) 1132 outline += 1; 1133 fprintf(fp, "#define YYPURE %d\n", pure_parser); 1134 putc_code(fp, '\n'); 1135 } 1136 1137 static void 1138 output_stype(FILE * fp) 1139 { 1140 if (!unionized && ntags == 0) 1141 { 1142 putc_code(fp, '\n'); 1143 putl_code(fp, "#ifndef YYSTYPE\n"); 1144 putl_code(fp, "typedef int YYSTYPE;\n"); 1145 putl_code(fp, "#endif\n"); 1146 } 1147 } 1148 1149 static void 1150 output_trailing_text(void) 1151 { 1152 int c, last; 1153 FILE *in; 1154 1155 if (line == 0) 1156 return; 1157 1158 in = input_file; 1159 c = *cptr; 1160 if (c == '\n') 1161 { 1162 ++lineno; 1163 if ((c = getc(in)) == EOF) 1164 return; 1165 write_input_lineno(); 1166 putc_code(code_file, c); 1167 last = c; 1168 } 1169 else 1170 { 1171 write_input_lineno(); 1172 do 1173 { 1174 putc_code(code_file, c); 1175 } 1176 while ((c = *++cptr) != '\n'); 1177 putc_code(code_file, c); 1178 last = '\n'; 1179 } 1180 1181 while ((c = getc(in)) != EOF) 1182 { 1183 putc_code(code_file, c); 1184 last = c; 1185 } 1186 1187 if (last != '\n') 1188 { 1189 putc_code(code_file, '\n'); 1190 } 1191 write_code_lineno(code_file); 1192 } 1193 1194 static void 1195 output_semantic_actions(void) 1196 { 1197 int c, last; 1198 1199 rewind(action_file); 1200 if ((c = getc(action_file)) == EOF) 1201 return; 1202 1203 last = c; 1204 putc_code(code_file, c); 1205 while ((c = getc(action_file)) != EOF) 1206 { 1207 putc_code(code_file, c); 1208 last = c; 1209 } 1210 1211 if (last != '\n') 1212 { 1213 putc_code(code_file, '\n'); 1214 } 1215 1216 write_code_lineno(code_file); 1217 } 1218 1219 static void 1220 output_parse_decl(FILE * fp) 1221 { 1222 putl_code(fp, "\n"); 1223 putl_code(fp, "/* compatibility with bison */\n"); 1224 putl_code(fp, "#ifdef YYPARSE_PARAM\n"); 1225 putl_code(fp, "/* compatibility with FreeBSD */\n"); 1226 putl_code(fp, "# ifdef YYPARSE_PARAM_TYPE\n"); 1227 putl_code(fp, 1228 "# define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM)\n"); 1229 putl_code(fp, "# else\n"); 1230 putl_code(fp, "# define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM)\n"); 1231 putl_code(fp, "# endif\n"); 1232 putl_code(fp, "#else\n"); 1233 1234 puts_code(fp, "# define YYPARSE_DECL() yyparse("); 1235 if (!parse_param) 1236 puts_code(fp, "void"); 1237 else 1238 { 1239 param *p; 1240 for (p = parse_param; p; p = p->next) 1241 fprintf(fp, "%s %s%s%s", p->type, p->name, p->type2, 1242 p->next ? ", " : ""); 1243 } 1244 putl_code(fp, ")\n"); 1245 1246 putl_code(fp, "#endif\n"); 1247 } 1248 1249 static void 1250 output_lex_decl(FILE * fp) 1251 { 1252 putl_code(fp, "\n"); 1253 putl_code(fp, "/* Parameters sent to lex. */\n"); 1254 putl_code(fp, "#ifdef YYLEX_PARAM\n"); 1255 if (pure_parser) 1256 { 1257 putl_code(fp, "# ifdef YYLEX_PARAM_TYPE\n"); 1258 putl_code(fp, "# define YYLEX_DECL() yylex(YYSTYPE *yylval," 1259 " YYLEX_PARAM_TYPE YYLEX_PARAM)\n"); 1260 putl_code(fp, "# else\n"); 1261 putl_code(fp, "# define YYLEX_DECL() yylex(YYSTYPE *yylval," 1262 " void * YYLEX_PARAM)\n"); 1263 putl_code(fp, "# endif\n"); 1264 putl_code(fp, "# define YYLEX yylex(&yylval, YYLEX_PARAM)\n"); 1265 } 1266 else 1267 { 1268 putl_code(fp, "# define YYLEX_DECL() yylex(void *YYLEX_PARAM)\n"); 1269 putl_code(fp, "# define YYLEX yylex(YYLEX_PARAM)\n"); 1270 } 1271 putl_code(fp, "#else\n"); 1272 if (pure_parser && lex_param) 1273 { 1274 param *p; 1275 puts_code(fp, "# define YYLEX_DECL() yylex(YYSTYPE *yylval, "); 1276 for (p = lex_param; p; p = p->next) 1277 fprintf(fp, "%s %s%s%s", p->type, p->name, p->type2, 1278 p->next ? ", " : ""); 1279 putl_code(fp, ")\n"); 1280 1281 puts_code(fp, "# define YYLEX yylex(&yylval, "); 1282 for (p = lex_param; p; p = p->next) 1283 fprintf(fp, "%s%s", p->name, p->next ? ", " : ""); 1284 putl_code(fp, ")\n"); 1285 } 1286 else if (pure_parser) 1287 { 1288 putl_code(fp, "# define YYLEX_DECL() yylex(YYSTYPE *yylval)\n"); 1289 putl_code(fp, "# define YYLEX yylex(&yylval)\n"); 1290 } 1291 else if (lex_param) 1292 { 1293 param *p; 1294 puts_code(fp, "# define YYLEX_DECL() yylex("); 1295 for (p = lex_param; p; p = p->next) 1296 fprintf(fp, "%s %s%s%s", p->type, p->name, p->type2, 1297 p->next ? ", " : ""); 1298 putl_code(fp, ")\n"); 1299 1300 puts_code(fp, "# define YYLEX yylex("); 1301 for (p = lex_param; p; p = p->next) 1302 fprintf(fp, "%s%s", p->name, p->next ? ", " : ""); 1303 putl_code(fp, ")\n"); 1304 } 1305 else 1306 { 1307 putl_code(fp, "# define YYLEX_DECL() yylex(void)\n"); 1308 putl_code(fp, "# define YYLEX yylex()\n"); 1309 } 1310 putl_code(fp, "#endif\n"); 1311 } 1312 1313 static void 1314 output_error_decl(FILE * fp) 1315 { 1316 putl_code(fp, "\n"); 1317 putl_code(fp, "/* Parameters sent to yyerror. */\n"); 1318 if (parse_param) 1319 { 1320 param *p; 1321 1322 putl_code(fp, "#ifndef YYERROR_DECL\n"); 1323 fprintf(fp, "#define YYERROR_DECL() yyerror("); 1324 for (p = parse_param; p; p = p->next) 1325 fprintf(fp, "%s %s%s, ", p->type, p->name, p->type2); 1326 putl_code(fp, "const char *s)\n"); 1327 putl_code(fp, "#endif\n"); 1328 1329 putl_code(fp, "#ifndef YYERROR_CALL\n"); 1330 puts_code(fp, "#define YYERROR_CALL(msg) yyerror("); 1331 1332 for (p = parse_param; p; p = p->next) 1333 fprintf(fp, "%s, ", p->name); 1334 1335 putl_code(fp, "msg)\n"); 1336 putl_code(fp, "#endif\n"); 1337 } 1338 else 1339 { 1340 putl_code(fp, "#ifndef YYERROR_DECL\n"); 1341 putl_code(fp, "#define YYERROR_DECL() yyerror(const char *s)\n"); 1342 putl_code(fp, "#endif\n"); 1343 putl_code(fp, "#ifndef YYERROR_CALL\n"); 1344 putl_code(fp, "#define YYERROR_CALL(msg) yyerror(msg)\n"); 1345 putl_code(fp, "#endif\n"); 1346 } 1347 } 1348 1349 static void 1350 free_itemsets(void) 1351 { 1352 core *cp, *next; 1353 1354 FREE(state_table); 1355 for (cp = first_state; cp; cp = next) 1356 { 1357 next = cp->next; 1358 FREE(cp); 1359 } 1360 } 1361 1362 static void 1363 free_shifts(void) 1364 { 1365 shifts *sp, *next; 1366 1367 FREE(shift_table); 1368 for (sp = first_shift; sp; sp = next) 1369 { 1370 next = sp->next; 1371 FREE(sp); 1372 } 1373 } 1374 1375 static void 1376 free_reductions(void) 1377 { 1378 reductions *rp, *next; 1379 1380 FREE(reduction_table); 1381 for (rp = first_reduction; rp; rp = next) 1382 { 1383 next = rp->next; 1384 FREE(rp); 1385 } 1386 } 1387 1388 static void 1389 output_yyerror_call(const char *msg) 1390 { 1391 FILE *fp = code_file; 1392 1393 puts_code(fp, " yyerror("); 1394 if (parse_param) 1395 { 1396 param *p; 1397 for (p = parse_param; p; p = p->next) 1398 fprintf(fp, "%s, ", p->name); 1399 } 1400 puts_code(fp, "\""); 1401 puts_code(fp, msg); 1402 putl_code(fp, "\");\n"); 1403 } 1404 1405 static void 1406 output_externs(FILE * fp, const char *const section[]) 1407 { 1408 int c; 1409 int i; 1410 const char *s; 1411 1412 for (i = 0; (s = section[i]) != 0; ++i) 1413 { 1414 if (*s && *s != '#') 1415 fputs("extern\t", fp); 1416 while ((c = *s) != 0) 1417 { 1418 putc(c, fp); 1419 ++s; 1420 } 1421 if (fp == code_file) 1422 ++outline; 1423 putc('\n', fp); 1424 } 1425 } 1426 1427 void 1428 output(void) 1429 { 1430 FILE *fp; 1431 1432 free_itemsets(); 1433 free_shifts(); 1434 free_reductions(); 1435 1436 if (iflag) 1437 { 1438 ++outline; 1439 fprintf(code_file, "#include \"%s\"\n", externs_file_name); 1440 fp = externs_file; 1441 } 1442 else 1443 fp = code_file; 1444 1445 output_prefix(iflag ? externs_file : output_file); 1446 output_pure_parser(fp); 1447 output_stored_text(fp); 1448 output_stype(fp); 1449 output_parse_decl(fp); 1450 output_lex_decl(fp); 1451 output_error_decl(fp); 1452 write_section(fp, xdecls); 1453 1454 if (iflag) 1455 { 1456 output_externs(externs_file, global_vars); 1457 if (!pure_parser) 1458 output_externs(externs_file, impure_vars); 1459 } 1460 1461 if (iflag) 1462 { 1463 if (dflag) 1464 { 1465 ++outline; 1466 fprintf(code_file, "#include \"%s\"\n", defines_file_name); 1467 } 1468 else 1469 output_defines(externs_file); 1470 } 1471 else 1472 { 1473 putc_code(code_file, '\n'); 1474 output_defines(code_file); 1475 } 1476 1477 if (dflag) 1478 output_defines(defines_file); 1479 1480 output_rule_data(); 1481 output_yydefred(); 1482 output_actions(); 1483 free_parser(); 1484 output_debug(); 1485 if (rflag) 1486 { 1487 output_prefix(code_file); 1488 write_section(code_file, xdecls); 1489 write_section(code_file, tables); 1490 } 1491 write_section(code_file, global_vars); 1492 if (!pure_parser) 1493 { 1494 write_section(code_file, impure_vars); 1495 } 1496 write_section(code_file, hdr_defs); 1497 if (!pure_parser) 1498 { 1499 write_section(code_file, hdr_vars); 1500 } 1501 output_trailing_text(); 1502 write_section(code_file, body_1); 1503 if (pure_parser) 1504 { 1505 write_section(code_file, body_vars); 1506 } 1507 write_section(code_file, body_2); 1508 output_yyerror_call("syntax error"); 1509 write_section(code_file, body_3); 1510 output_semantic_actions(); 1511 write_section(code_file, trailer); 1512 output_yyerror_call("yacc stack overflow"); 1513 write_section(code_file, trailer_2); 1514 } 1515 1516 #ifdef NO_LEAKS 1517 void 1518 output_leaks(void) 1519 { 1520 DO_FREE(tally); 1521 DO_FREE(width); 1522 DO_FREE(order); 1523 } 1524 #endif 1525