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