1 /* $NetBSD: output.c,v 1.9 2013/04/06 14:52:24 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.9 2013/04/06 14:52:24 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, "yyname"); 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 930 symnam = TMALLOC(const char *, max + 1); 931 NO_SPACE(symnam); 932 933 /* Note that it is not necessary to initialize the element */ 934 /* symnam[max]. */ 935 for (i = 0; i < max; ++i) 936 symnam[i] = 0; 937 for (i = ntokens - 1; i >= 2; --i) 938 symnam[symbol_value[i]] = symbol_name[i]; 939 symnam[0] = "end-of-file"; 940 941 output_line("#if YYDEBUG"); 942 943 start_str_table("name"); 944 j = 80; 945 for (i = 0; i <= max; ++i) 946 { 947 if ((s = symnam[i]) != 0) 948 { 949 if (s[0] == '"') 950 { 951 k = 7; 952 while (*++s != '"') 953 { 954 ++k; 955 if (*s == '\\') 956 { 957 k += 2; 958 if (*++s == '\\') 959 ++k; 960 } 961 } 962 j += k; 963 if (j > 80) 964 { 965 output_newline(); 966 j = k; 967 } 968 fprintf(output_file, "\"\\\""); 969 s = symnam[i]; 970 while (*++s != '"') 971 { 972 if (*s == '\\') 973 { 974 fprintf(output_file, "\\\\"); 975 if (*++s == '\\') 976 fprintf(output_file, "\\\\"); 977 else 978 putc(*s, output_file); 979 } 980 else 981 putc(*s, output_file); 982 } 983 fprintf(output_file, "\\\"\","); 984 } 985 else if (s[0] == '\'') 986 { 987 if (s[1] == '"') 988 { 989 j += 7; 990 if (j > 80) 991 { 992 output_newline(); 993 j = 7; 994 } 995 fprintf(output_file, "\"'\\\"'\","); 996 } 997 else 998 { 999 k = 5; 1000 while (*++s != '\'') 1001 { 1002 ++k; 1003 if (*s == '\\') 1004 { 1005 k += 2; 1006 if (*++s == '\\') 1007 ++k; 1008 } 1009 } 1010 j += k; 1011 if (j > 80) 1012 { 1013 output_newline(); 1014 j = k; 1015 } 1016 fprintf(output_file, "\"'"); 1017 s = symnam[i]; 1018 while (*++s != '\'') 1019 { 1020 if (*s == '\\') 1021 { 1022 fprintf(output_file, "\\\\"); 1023 if (*++s == '\\') 1024 fprintf(output_file, "\\\\"); 1025 else 1026 putc(*s, output_file); 1027 } 1028 else 1029 putc(*s, output_file); 1030 } 1031 fprintf(output_file, "'\","); 1032 } 1033 } 1034 else 1035 { 1036 k = (int)strlen(s) + 3; 1037 j += k; 1038 if (j > 80) 1039 { 1040 output_newline(); 1041 j = k; 1042 } 1043 putc('"', output_file); 1044 do 1045 { 1046 putc(*s, output_file); 1047 } 1048 while (*++s); 1049 fprintf(output_file, "\","); 1050 } 1051 } 1052 else 1053 { 1054 j += 2; 1055 if (j > 80) 1056 { 1057 output_newline(); 1058 j = 2; 1059 } 1060 fprintf(output_file, "0,"); 1061 } 1062 } 1063 end_table(); 1064 FREE(symnam); 1065 1066 start_str_table("rule"); 1067 for (i = 2; i < nrules; ++i) 1068 { 1069 fprintf(output_file, "\"%s :", symbol_name[rlhs[i]]); 1070 for (j = rrhs[i]; ritem[j] > 0; ++j) 1071 { 1072 s = symbol_name[ritem[j]]; 1073 if (s[0] == '"') 1074 { 1075 fprintf(output_file, " \\\""); 1076 while (*++s != '"') 1077 { 1078 if (*s == '\\') 1079 { 1080 if (s[1] == '\\') 1081 fprintf(output_file, "\\\\\\\\"); 1082 else 1083 fprintf(output_file, "\\\\%c", s[1]); 1084 ++s; 1085 } 1086 else 1087 putc(*s, output_file); 1088 } 1089 fprintf(output_file, "\\\""); 1090 } 1091 else if (s[0] == '\'') 1092 { 1093 if (s[1] == '"') 1094 fprintf(output_file, " '\\\"'"); 1095 else if (s[1] == '\\') 1096 { 1097 if (s[2] == '\\') 1098 fprintf(output_file, " '\\\\\\\\"); 1099 else 1100 fprintf(output_file, " '\\\\%c", s[2]); 1101 s += 2; 1102 while (*++s != '\'') 1103 putc(*s, output_file); 1104 putc('\'', output_file); 1105 } 1106 else 1107 fprintf(output_file, " '%c'", s[1]); 1108 } 1109 else 1110 fprintf(output_file, " %s", s); 1111 } 1112 fprintf(output_file, "\","); 1113 output_newline(); 1114 } 1115 1116 end_table(); 1117 output_line("#endif"); 1118 } 1119 1120 static void 1121 output_pure_parser(FILE * fp) 1122 { 1123 putc_code(fp, '\n'); 1124 1125 if (fp == code_file) 1126 outline += 1; 1127 fprintf(fp, "#define YYPURE %d\n", pure_parser); 1128 putc_code(fp, '\n'); 1129 } 1130 1131 static void 1132 output_stype(FILE * fp) 1133 { 1134 if (!unionized && ntags == 0) 1135 { 1136 putc_code(fp, '\n'); 1137 putl_code(fp, "#ifndef YYSTYPE\n"); 1138 putl_code(fp, "typedef int YYSTYPE;\n"); 1139 putl_code(fp, "#endif\n"); 1140 } 1141 } 1142 1143 static void 1144 output_trailing_text(void) 1145 { 1146 int c, last; 1147 FILE *in; 1148 1149 if (line == 0) 1150 return; 1151 1152 in = input_file; 1153 c = *cptr; 1154 if (c == '\n') 1155 { 1156 ++lineno; 1157 if ((c = getc(in)) == EOF) 1158 return; 1159 write_input_lineno(); 1160 putc_code(code_file, c); 1161 last = c; 1162 } 1163 else 1164 { 1165 write_input_lineno(); 1166 do 1167 { 1168 putc_code(code_file, c); 1169 } 1170 while ((c = *++cptr) != '\n'); 1171 putc_code(code_file, c); 1172 last = '\n'; 1173 } 1174 1175 while ((c = getc(in)) != EOF) 1176 { 1177 putc_code(code_file, c); 1178 last = c; 1179 } 1180 1181 if (last != '\n') 1182 { 1183 putc_code(code_file, '\n'); 1184 } 1185 write_code_lineno(code_file); 1186 } 1187 1188 static void 1189 output_semantic_actions(void) 1190 { 1191 int c, last; 1192 1193 rewind(action_file); 1194 if ((c = getc(action_file)) == EOF) 1195 return; 1196 1197 last = c; 1198 putc_code(code_file, c); 1199 while ((c = getc(action_file)) != EOF) 1200 { 1201 putc_code(code_file, c); 1202 last = c; 1203 } 1204 1205 if (last != '\n') 1206 { 1207 putc_code(code_file, '\n'); 1208 } 1209 1210 write_code_lineno(code_file); 1211 } 1212 1213 static void 1214 output_parse_decl(FILE * fp) 1215 { 1216 putl_code(fp, "\n"); 1217 putl_code(fp, "/* compatibility with bison */\n"); 1218 putl_code(fp, "#ifdef YYPARSE_PARAM\n"); 1219 putl_code(fp, "/* compatibility with FreeBSD */\n"); 1220 putl_code(fp, "# ifdef YYPARSE_PARAM_TYPE\n"); 1221 putl_code(fp, 1222 "# define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM)\n"); 1223 putl_code(fp, "# else\n"); 1224 putl_code(fp, "# define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM)\n"); 1225 putl_code(fp, "# endif\n"); 1226 putl_code(fp, "#else\n"); 1227 1228 puts_code(fp, "# define YYPARSE_DECL() yyparse("); 1229 if (!parse_param) 1230 puts_code(fp, "void"); 1231 else 1232 { 1233 param *p; 1234 for (p = parse_param; p; p = p->next) 1235 fprintf(fp, "%s %s%s%s", p->type, p->name, p->type2, 1236 p->next ? ", " : ""); 1237 } 1238 putl_code(fp, ")\n"); 1239 1240 putl_code(fp, "#endif\n"); 1241 } 1242 1243 static void 1244 output_lex_decl(FILE * fp) 1245 { 1246 putl_code(fp, "\n"); 1247 putl_code(fp, "/* Parameters sent to lex. */\n"); 1248 putl_code(fp, "#ifdef YYLEX_PARAM\n"); 1249 if (pure_parser) 1250 { 1251 putl_code(fp, "# ifdef YYLEX_PARAM_TYPE\n"); 1252 putl_code(fp, "# define YYLEX_DECL() yylex(YYSTYPE *yylval," 1253 " YYLEX_PARAM_TYPE YYLEX_PARAM)\n"); 1254 putl_code(fp, "# else\n"); 1255 putl_code(fp, "# define YYLEX_DECL() yylex(YYSTYPE *yylval," 1256 " void * YYLEX_PARAM)\n"); 1257 putl_code(fp, "# endif\n"); 1258 putl_code(fp, "# define YYLEX yylex(&yylval, YYLEX_PARAM)\n"); 1259 } 1260 else 1261 { 1262 putl_code(fp, "# define YYLEX_DECL() yylex(void *YYLEX_PARAM)\n"); 1263 putl_code(fp, "# define YYLEX yylex(YYLEX_PARAM)\n"); 1264 } 1265 putl_code(fp, "#else\n"); 1266 if (pure_parser && lex_param) 1267 { 1268 param *p; 1269 puts_code(fp, "# define YYLEX_DECL() yylex(YYSTYPE *yylval, "); 1270 for (p = lex_param; p; p = p->next) 1271 fprintf(fp, "%s %s%s%s", p->type, p->name, p->type2, 1272 p->next ? ", " : ""); 1273 putl_code(fp, ")\n"); 1274 1275 puts_code(fp, "# define YYLEX yylex(&yylval, "); 1276 for (p = lex_param; p; p = p->next) 1277 fprintf(fp, "%s%s", p->name, p->next ? ", " : ""); 1278 putl_code(fp, ")\n"); 1279 } 1280 else if (pure_parser) 1281 { 1282 putl_code(fp, "# define YYLEX_DECL() yylex(YYSTYPE *yylval)\n"); 1283 putl_code(fp, "# define YYLEX yylex(&yylval)\n"); 1284 } 1285 else if (lex_param) 1286 { 1287 param *p; 1288 puts_code(fp, "# define YYLEX_DECL() yylex("); 1289 for (p = lex_param; p; p = p->next) 1290 fprintf(fp, "%s %s%s%s", p->type, p->name, p->type2, 1291 p->next ? ", " : ""); 1292 putl_code(fp, ")\n"); 1293 1294 puts_code(fp, "# define YYLEX yylex("); 1295 for (p = lex_param; p; p = p->next) 1296 fprintf(fp, "%s%s", p->name, p->next ? ", " : ""); 1297 putl_code(fp, ")\n"); 1298 } 1299 else 1300 { 1301 putl_code(fp, "# define YYLEX_DECL() yylex(void)\n"); 1302 putl_code(fp, "# define YYLEX yylex()\n"); 1303 } 1304 putl_code(fp, "#endif\n"); 1305 } 1306 1307 static void 1308 output_error_decl(FILE * fp) 1309 { 1310 putl_code(fp, "\n"); 1311 putl_code(fp, "/* Parameters sent to yyerror. */\n"); 1312 if (parse_param) 1313 { 1314 param *p; 1315 1316 putl_code(fp, "#ifndef YYERROR_DECL\n"); 1317 fprintf(fp, "#define YYERROR_DECL() yyerror("); 1318 for (p = parse_param; p; p = p->next) 1319 fprintf(fp, "%s %s%s, ", p->type, p->name, p->type2); 1320 putl_code(fp, "const char *s)\n"); 1321 putl_code(fp, "#endif\n"); 1322 1323 putl_code(fp, "#ifndef YYERROR_CALL\n"); 1324 puts_code(fp, "#define YYERROR_CALL(msg) yyerror("); 1325 1326 for (p = parse_param; p; p = p->next) 1327 fprintf(fp, "%s, ", p->name); 1328 1329 putl_code(fp, "msg)\n"); 1330 putl_code(fp, "#endif\n"); 1331 } 1332 else 1333 { 1334 putl_code(fp, "#ifndef YYERROR_DECL\n"); 1335 putl_code(fp, "#define YYERROR_DECL() yyerror(const char *s)\n"); 1336 putl_code(fp, "#endif\n"); 1337 putl_code(fp, "#ifndef YYERROR_CALL\n"); 1338 putl_code(fp, "#define YYERROR_CALL(msg) yyerror(msg)\n"); 1339 putl_code(fp, "#endif\n"); 1340 } 1341 } 1342 1343 static void 1344 free_itemsets(void) 1345 { 1346 core *cp, *next; 1347 1348 FREE(state_table); 1349 for (cp = first_state; cp; cp = next) 1350 { 1351 next = cp->next; 1352 FREE(cp); 1353 } 1354 } 1355 1356 static void 1357 free_shifts(void) 1358 { 1359 shifts *sp, *next; 1360 1361 FREE(shift_table); 1362 for (sp = first_shift; sp; sp = next) 1363 { 1364 next = sp->next; 1365 FREE(sp); 1366 } 1367 } 1368 1369 static void 1370 free_reductions(void) 1371 { 1372 reductions *rp, *next; 1373 1374 FREE(reduction_table); 1375 for (rp = first_reduction; rp; rp = next) 1376 { 1377 next = rp->next; 1378 FREE(rp); 1379 } 1380 } 1381 1382 static void 1383 output_yyerror_call(const char *msg) 1384 { 1385 FILE *fp = code_file; 1386 1387 puts_code(fp, " yyerror("); 1388 if (parse_param) 1389 { 1390 param *p; 1391 for (p = parse_param; p; p = p->next) 1392 fprintf(fp, "%s, ", p->name); 1393 } 1394 puts_code(fp, "\""); 1395 puts_code(fp, msg); 1396 putl_code(fp, "\");\n"); 1397 } 1398 1399 static void 1400 output_externs(FILE * fp, const char *const section[]) 1401 { 1402 int c; 1403 int i; 1404 const char *s; 1405 1406 for (i = 0; (s = section[i]) != 0; ++i) 1407 { 1408 if (*s && *s != '#') 1409 fputs("extern\t", fp); 1410 while ((c = *s) != 0) 1411 { 1412 putc(c, fp); 1413 ++s; 1414 } 1415 if (fp == code_file) 1416 ++outline; 1417 putc('\n', fp); 1418 } 1419 } 1420 1421 void 1422 output(void) 1423 { 1424 FILE *fp; 1425 1426 free_itemsets(); 1427 free_shifts(); 1428 free_reductions(); 1429 1430 if (iflag) 1431 { 1432 ++outline; 1433 fprintf(code_file, "#include \"%s\"\n", externs_file_name); 1434 fp = externs_file; 1435 } 1436 else 1437 fp = code_file; 1438 1439 output_prefix(iflag ? externs_file : output_file); 1440 output_pure_parser(fp); 1441 output_stored_text(fp); 1442 output_stype(fp); 1443 output_parse_decl(fp); 1444 output_lex_decl(fp); 1445 output_error_decl(fp); 1446 write_section(fp, xdecls); 1447 1448 if (iflag) 1449 { 1450 output_externs(externs_file, global_vars); 1451 if (!pure_parser) 1452 output_externs(externs_file, impure_vars); 1453 } 1454 1455 if (iflag) 1456 { 1457 if (dflag) 1458 { 1459 ++outline; 1460 fprintf(code_file, "#include \"%s\"\n", defines_file_name); 1461 } 1462 else 1463 output_defines(externs_file); 1464 } 1465 else 1466 { 1467 putc_code(code_file, '\n'); 1468 output_defines(code_file); 1469 } 1470 1471 if (dflag) 1472 output_defines(defines_file); 1473 1474 output_rule_data(); 1475 output_yydefred(); 1476 output_actions(); 1477 free_parser(); 1478 output_debug(); 1479 if (rflag) 1480 { 1481 output_prefix(code_file); 1482 write_section(code_file, xdecls); 1483 write_section(code_file, tables); 1484 } 1485 write_section(code_file, global_vars); 1486 if (!pure_parser) 1487 { 1488 write_section(code_file, impure_vars); 1489 } 1490 write_section(code_file, hdr_defs); 1491 if (!pure_parser) 1492 { 1493 write_section(code_file, hdr_vars); 1494 } 1495 output_trailing_text(); 1496 write_section(code_file, body_1); 1497 if (pure_parser) 1498 { 1499 write_section(code_file, body_vars); 1500 } 1501 write_section(code_file, body_2); 1502 output_yyerror_call("syntax error"); 1503 write_section(code_file, body_3); 1504 output_semantic_actions(); 1505 write_section(code_file, trailer); 1506 output_yyerror_call("yacc stack overflow"); 1507 write_section(code_file, trailer_2); 1508 } 1509 1510 #ifdef NO_LEAKS 1511 void 1512 output_leaks(void) 1513 { 1514 DO_FREE(tally); 1515 DO_FREE(width); 1516 DO_FREE(order); 1517 } 1518 #endif 1519