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