1 /* $OpenBSD: output.c,v 1.26 2016/09/21 16:26:30 otto Exp $ */ 2 /* $NetBSD: output.c,v 1.4 1996/03/19 03:21:41 jtc Exp $ */ 3 4 /* 5 * Copyright (c) 1989 The Regents of the University of California. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by 9 * Robert Paul Corbett. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. Neither the name of the University nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36 #include "defs.h" 37 38 static int nvectors; 39 static int nentries; 40 static short **froms; 41 static short **tos; 42 static short *tally; 43 static short *width; 44 static short *state_count; 45 static short *order; 46 static short *base; 47 static short *pos; 48 static int maxtable; 49 static short *table; 50 static short *check; 51 static int lowzero; 52 static int high; 53 54 void output_prefix(void); 55 void output_rule_data(void); 56 void output_yydefred(void); 57 void output_actions(void); 58 void token_actions(void); 59 void goto_actions(void); 60 int default_goto(int); 61 void save_column(int, int); 62 void sort_actions(void); 63 void pack_table(void); 64 int matching_vector(int); 65 int pack_vector(int); 66 void output_base(void); 67 void output_table(void); 68 void output_check(void); 69 int is_C_identifier(char *); 70 void output_defines(void); 71 void output_stored_text(void); 72 void output_debug(void); 73 void output_stype(void); 74 void output_trailing_text(void); 75 void output_semantic_actions(void); 76 void free_itemsets(void); 77 void free_shifts(void); 78 void free_reductions(void); 79 80 void 81 output(void) 82 { 83 free_itemsets(); 84 free_shifts(); 85 free_reductions(); 86 output_prefix(); 87 output_stored_text(); 88 output_defines(); 89 output_rule_data(); 90 output_yydefred(); 91 output_actions(); 92 free_parser(); 93 output_debug(); 94 output_stype(); 95 if (rflag) 96 write_section(tables); 97 write_section(header); 98 output_trailing_text(); 99 write_section(body); 100 output_semantic_actions(); 101 write_section(trailer); 102 } 103 104 105 void 106 output_prefix(void) 107 { 108 if (symbol_prefix == NULL) 109 symbol_prefix = "yy"; 110 else { 111 ++outline; 112 fprintf(code_file, "#define yyparse %sparse\n", symbol_prefix); 113 ++outline; 114 fprintf(code_file, "#define yylex %slex\n", symbol_prefix); 115 ++outline; 116 fprintf(code_file, "#define yyerror %serror\n", symbol_prefix); 117 ++outline; 118 fprintf(code_file, "#define yychar %schar\n", symbol_prefix); 119 ++outline; 120 fprintf(code_file, "#define yyval %sval\n", symbol_prefix); 121 ++outline; 122 fprintf(code_file, "#define yylval %slval\n", symbol_prefix); 123 ++outline; 124 fprintf(code_file, "#define yydebug %sdebug\n", symbol_prefix); 125 ++outline; 126 fprintf(code_file, "#define yynerrs %snerrs\n", symbol_prefix); 127 ++outline; 128 fprintf(code_file, "#define yyerrflag %serrflag\n", symbol_prefix); 129 ++outline; 130 fprintf(code_file, "#define yyss %sss\n", symbol_prefix); 131 ++outline; 132 fprintf(code_file, "#define yysslim %ssslim\n", symbol_prefix); 133 ++outline; 134 fprintf(code_file, "#define yyssp %sssp\n", symbol_prefix); 135 ++outline; 136 fprintf(code_file, "#define yyvs %svs\n", symbol_prefix); 137 ++outline; 138 fprintf(code_file, "#define yyvsp %svsp\n", symbol_prefix); 139 ++outline; 140 fprintf(code_file, "#define yystacksize %sstacksize\n", symbol_prefix); 141 ++outline; 142 fprintf(code_file, "#define yylhs %slhs\n", symbol_prefix); 143 ++outline; 144 fprintf(code_file, "#define yylen %slen\n", symbol_prefix); 145 ++outline; 146 fprintf(code_file, "#define yydefred %sdefred\n", symbol_prefix); 147 ++outline; 148 fprintf(code_file, "#define yydgoto %sdgoto\n", symbol_prefix); 149 ++outline; 150 fprintf(code_file, "#define yysindex %ssindex\n", symbol_prefix); 151 ++outline; 152 fprintf(code_file, "#define yyrindex %srindex\n", symbol_prefix); 153 ++outline; 154 fprintf(code_file, "#define yygindex %sgindex\n", symbol_prefix); 155 ++outline; 156 fprintf(code_file, "#define yytable %stable\n", symbol_prefix); 157 ++outline; 158 fprintf(code_file, "#define yycheck %scheck\n", symbol_prefix); 159 ++outline; 160 fprintf(code_file, "#define yyname %sname\n", symbol_prefix); 161 ++outline; 162 fprintf(code_file, "#define yyrule %srule\n", symbol_prefix); 163 } 164 ++outline; 165 fprintf(code_file, "#define YYPREFIX \"%s\"\n", symbol_prefix); 166 } 167 168 169 void 170 output_rule_data(void) 171 { 172 int i; 173 int j; 174 175 fprintf(output_file, 176 "const short %slhs[] =\n" 177 "\t{%42d,", symbol_prefix, symbol_value[start_symbol]); 178 179 j = 10; 180 for (i = 3; i < nrules; i++) { 181 if (j >= 10) { 182 if (!rflag) 183 ++outline; 184 putc('\n', output_file); 185 j = 1; 186 } else 187 ++j; 188 fprintf(output_file, "%5d,", symbol_value[rlhs[i]]); 189 } 190 if (!rflag) 191 outline += 2; 192 fprintf(output_file, "\n};\n"); 193 194 fprintf(output_file, 195 "const short %slen[] =\n" 196 "\t{%42d,", symbol_prefix, 2); 197 198 j = 10; 199 for (i = 3; i < nrules; i++) { 200 if (j >= 10) { 201 if (!rflag) 202 ++outline; 203 putc('\n', output_file); 204 j = 1; 205 } else 206 j++; 207 fprintf(output_file, "%5d,", rrhs[i + 1] - rrhs[i] - 1); 208 } 209 if (!rflag) 210 outline += 2; 211 fprintf(output_file, "\n};\n"); 212 } 213 214 215 void 216 output_yydefred(void) 217 { 218 int i, j; 219 220 fprintf(output_file, 221 "const short %sdefred[] =\n" 222 "\t{%39d,", 223 symbol_prefix, (defred[0] ? defred[0] - 2 : 0)); 224 225 j = 10; 226 for (i = 1; i < nstates; i++) { 227 if (j < 10) 228 ++j; 229 else { 230 if (!rflag) 231 ++outline; 232 putc('\n', output_file); 233 j = 1; 234 } 235 fprintf(output_file, "%5d,", (defred[i] ? defred[i] - 2 : 0)); 236 } 237 238 if (!rflag) 239 outline += 2; 240 fprintf(output_file, "\n};\n"); 241 } 242 243 244 void 245 output_actions(void) 246 { 247 nvectors = 2 * nstates + nvars; 248 249 froms = NEW2(nvectors, short *); 250 tos = NEW2(nvectors, short *); 251 tally = NEW2(nvectors, short); 252 width = NEW2(nvectors, short); 253 254 token_actions(); 255 free(lookaheads); 256 free(LA); 257 free(LAruleno); 258 free(accessing_symbol); 259 260 goto_actions(); 261 free(goto_map + ntokens); 262 free(from_state); 263 free(to_state); 264 265 sort_actions(); 266 pack_table(); 267 output_base(); 268 output_table(); 269 output_check(); 270 } 271 272 273 void 274 token_actions(void) 275 { 276 int i, j; 277 int shiftcount, reducecount; 278 int max, min; 279 short *actionrow, *r, *s; 280 action *p; 281 282 actionrow = NEW2(2*ntokens, short); 283 for (i = 0; i < nstates; ++i) { 284 if (parser[i]) { 285 for (j = 0; j < 2 * ntokens; ++j) 286 actionrow[j] = 0; 287 shiftcount = 0; 288 reducecount = 0; 289 for (p = parser[i]; p; p = p->next) { 290 if (p->suppressed == 0) { 291 if (p->action_code == SHIFT) { 292 ++shiftcount; 293 actionrow[p->symbol] = p->number; 294 } else if (p->action_code == REDUCE && 295 p->number != defred[i]) { 296 ++reducecount; 297 actionrow[p->symbol + ntokens] = p->number; 298 } 299 } 300 } 301 302 tally[i] = shiftcount; 303 tally[nstates+i] = reducecount; 304 width[i] = 0; 305 width[nstates+i] = 0; 306 if (shiftcount > 0) { 307 froms[i] = r = NEW2(shiftcount, short); 308 tos[i] = s = NEW2(shiftcount, short); 309 min = MAXSHORT; 310 max = 0; 311 for (j = 0; j < ntokens; ++j) { 312 if (actionrow[j]) { 313 if (min > symbol_value[j]) 314 min = symbol_value[j]; 315 if (max < symbol_value[j]) 316 max = symbol_value[j]; 317 *r++ = symbol_value[j]; 318 *s++ = actionrow[j]; 319 } 320 } 321 width[i] = max - min + 1; 322 } 323 if (reducecount > 0) { 324 froms[nstates+i] = r = NEW2(reducecount, short); 325 tos[nstates+i] = s = NEW2(reducecount, short); 326 min = MAXSHORT; 327 max = 0; 328 for (j = 0; j < ntokens; ++j) { 329 if (actionrow[ntokens+j]) { 330 if (min > symbol_value[j]) 331 min = symbol_value[j]; 332 if (max < symbol_value[j]) 333 max = symbol_value[j]; 334 *r++ = symbol_value[j]; 335 *s++ = actionrow[ntokens+j] - 2; 336 } 337 } 338 width[nstates+i] = max - min + 1; 339 } 340 } 341 } 342 free(actionrow); 343 } 344 345 void 346 goto_actions(void) 347 { 348 int i, j, k; 349 350 state_count = NEW2(nstates, short); 351 352 k = default_goto(start_symbol + 1); 353 fprintf(output_file, "const short %sdgoto[] =\n" 354 "\t{%40d,", symbol_prefix, k); 355 save_column(start_symbol + 1, k); 356 357 j = 10; 358 for (i = start_symbol + 2; i < nsyms; i++) { 359 if (j >= 10) { 360 if (!rflag) 361 ++outline; 362 putc('\n', output_file); 363 j = 1; 364 } else 365 ++j; 366 367 k = default_goto(i); 368 fprintf(output_file, "%5d,", k); 369 save_column(i, k); 370 } 371 372 if (!rflag) 373 outline += 2; 374 fprintf(output_file, "\n};\n"); 375 free(state_count); 376 } 377 378 int 379 default_goto(int symbol) 380 { 381 int i; 382 int m; 383 int n; 384 int default_state; 385 int max; 386 387 m = goto_map[symbol]; 388 n = goto_map[symbol + 1]; 389 390 if (m == n) 391 return (0); 392 393 memset(state_count, 0, nstates * sizeof(short)); 394 395 for (i = m; i < n; i++) 396 state_count[to_state[i]]++; 397 398 max = 0; 399 default_state = 0; 400 for (i = 0; i < nstates; i++) { 401 if (state_count[i] > max) { 402 max = state_count[i]; 403 default_state = i; 404 } 405 } 406 407 return (default_state); 408 } 409 410 411 412 void 413 save_column(int symbol, int default_state) 414 { 415 int i; 416 int m; 417 int n; 418 short *sp; 419 short *sp1; 420 short *sp2; 421 int count; 422 int symno; 423 424 m = goto_map[symbol]; 425 n = goto_map[symbol + 1]; 426 427 count = 0; 428 for (i = m; i < n; i++) { 429 if (to_state[i] != default_state) 430 ++count; 431 } 432 if (count == 0) 433 return; 434 435 symno = symbol_value[symbol] + 2*nstates; 436 437 froms[symno] = sp1 = sp = NEW2(count, short); 438 tos[symno] = sp2 = NEW2(count, short); 439 440 for (i = m; i < n; i++) { 441 if (to_state[i] != default_state) { 442 *sp1++ = from_state[i]; 443 *sp2++ = to_state[i]; 444 } 445 } 446 447 tally[symno] = count; 448 width[symno] = sp1[-1] - sp[0] + 1; 449 } 450 451 void 452 sort_actions(void) 453 { 454 int i; 455 int j; 456 int k; 457 int t; 458 int w; 459 460 order = NEW2(nvectors, short); 461 nentries = 0; 462 463 for (i = 0; i < nvectors; i++) { 464 if (tally[i] > 0) { 465 t = tally[i]; 466 w = width[i]; 467 j = nentries - 1; 468 469 while (j >= 0 && (width[order[j]] < w)) 470 j--; 471 472 while (j >= 0 && (width[order[j]] == w) && 473 (tally[order[j]] < t)) 474 j--; 475 476 for (k = nentries - 1; k > j; k--) 477 order[k + 1] = order[k]; 478 479 order[j + 1] = i; 480 nentries++; 481 } 482 } 483 } 484 485 486 void 487 pack_table(void) 488 { 489 int i; 490 int place; 491 int state; 492 493 base = NEW2(nvectors, short); 494 pos = NEW2(nentries, short); 495 496 maxtable = 1000; 497 table = NEW2(maxtable, short); 498 check = NEW2(maxtable, short); 499 500 lowzero = 0; 501 high = 0; 502 503 for (i = 0; i < maxtable; i++) 504 check[i] = -1; 505 506 for (i = 0; i < nentries; i++) { 507 state = matching_vector(i); 508 509 if (state < 0) 510 place = pack_vector(i); 511 else 512 place = base[state]; 513 514 pos[i] = place; 515 base[order[i]] = place; 516 } 517 518 for (i = 0; i < nvectors; i++) { 519 free(froms[i]); 520 free(tos[i]); 521 } 522 523 free(froms); 524 free(tos); 525 free(pos); 526 } 527 528 529 /* The function matching_vector determines if the vector specified by */ 530 /* the input parameter matches a previously considered vector. The */ 531 /* test at the start of the function checks if the vector represents */ 532 /* a row of shifts over terminal symbols or a row of reductions, or a */ 533 /* column of shifts over a nonterminal symbol. Berkeley Yacc does not */ 534 /* check if a column of shifts over a nonterminal symbols matches a */ 535 /* previously considered vector. Because of the nature of LR parsing */ 536 /* tables, no two columns can match. Therefore, the only possible */ 537 /* match would be between a row and a column. Such matches are */ 538 /* unlikely. Therefore, to save time, no attempt is made to see if a */ 539 /* column matches a previously considered vector. */ 540 /* */ 541 /* Matching_vector is poorly designed. The test could easily be made */ 542 /* faster. Also, it depends on the vectors being in a specific */ 543 /* order. */ 544 545 int 546 matching_vector(int vector) 547 { 548 int i, j, k, t, w, match, prev; 549 550 i = order[vector]; 551 if (i >= 2*nstates) 552 return (-1); 553 554 t = tally[i]; 555 w = width[i]; 556 557 for (prev = vector - 1; prev >= 0; prev--) { 558 j = order[prev]; 559 if (width[j] != w || tally[j] != t) 560 return (-1); 561 562 match = 1; 563 for (k = 0; match && k < t; k++) { 564 if (tos[j][k] != tos[i][k] || 565 froms[j][k] != froms[i][k]) 566 match = 0; 567 } 568 569 if (match) 570 return (j); 571 } 572 573 return (-1); 574 } 575 576 577 578 int 579 pack_vector(int vector) 580 { 581 int i, j, k, l; 582 int t, loc, ok; 583 short *from, *to; 584 int newmax; 585 586 i = order[vector]; 587 t = tally[i]; 588 assert(t); 589 590 from = froms[i]; 591 to = tos[i]; 592 593 j = lowzero - from[0]; 594 for (k = 1; k < t; ++k) 595 if (lowzero - from[k] > j) 596 j = lowzero - from[k]; 597 for (;; ++j) { 598 if (j == 0) 599 continue; 600 ok = 1; 601 for (k = 0; ok && k < t; k++) { 602 loc = j + from[k]; 603 if (loc >= maxtable) { 604 if (loc >= MAXTABLE) 605 fatal("maximum table size exceeded"); 606 607 newmax = maxtable; 608 do { 609 newmax += 200; 610 } while (newmax <= loc); 611 table = realloc(table, newmax * sizeof(short)); 612 if (table == NULL) 613 no_space(); 614 check = realloc(check, newmax * sizeof(short)); 615 if (check == NULL) 616 no_space(); 617 for (l = maxtable; l < newmax; ++l) { 618 table[l] = 0; 619 check[l] = -1; 620 } 621 maxtable = newmax; 622 } 623 624 if (check[loc] != -1) 625 ok = 0; 626 } 627 for (k = 0; ok && k < vector; k++) { 628 if (pos[k] == j) 629 ok = 0; 630 } 631 if (ok) { 632 for (k = 0; k < t; k++) { 633 loc = j + from[k]; 634 table[loc] = to[k]; 635 check[loc] = from[k]; 636 if (loc > high) 637 high = loc; 638 } 639 640 while (lowzero < maxtable && check[lowzero] != -1) 641 ++lowzero; 642 643 return (j); 644 } 645 } 646 } 647 648 649 650 void 651 output_base(void) 652 { 653 int i, j; 654 655 fprintf(output_file, "const short %ssindex[] =\n" 656 "\t{%39d,", symbol_prefix, base[0]); 657 658 j = 10; 659 for (i = 1; i < nstates; i++) { 660 if (j >= 10) { 661 if (!rflag) 662 ++outline; 663 putc('\n', output_file); 664 j = 1; 665 } else 666 ++j; 667 fprintf(output_file, "%5d,", base[i]); 668 } 669 670 if (!rflag) 671 outline += 2; 672 fprintf(output_file, "};\n" 673 "const short %srindex[] =\n" 674 "\t{%39d,", symbol_prefix, base[nstates]); 675 676 j = 10; 677 for (i = nstates + 1; i < 2*nstates; i++) { 678 if (j >= 10) { 679 if (!rflag) 680 ++outline; 681 putc('\n', output_file); 682 j = 1; 683 } else 684 ++j; 685 fprintf(output_file, "%5d,", base[i]); 686 } 687 688 if (!rflag) 689 outline += 2; 690 fprintf(output_file, "};\n" 691 "const short %sgindex[] =\n" 692 "\t{%39d,", symbol_prefix, base[2*nstates]); 693 694 j = 10; 695 for (i = 2*nstates + 1; i < nvectors - 1; i++) { 696 if (j >= 10) { 697 if (!rflag) 698 ++outline; 699 putc('\n', output_file); 700 j = 1; 701 } else 702 ++j; 703 fprintf(output_file, "%5d,", base[i]); 704 } 705 706 if (!rflag) 707 outline += 2; 708 fprintf(output_file, "\n};\n"); 709 free(base); 710 } 711 712 713 void 714 output_table(void) 715 { 716 int i, j; 717 718 ++outline; 719 fprintf(code_file, "#define YYTABLESIZE %d\n", high); 720 fprintf(output_file, "const short %stable[] =\n" 721 "\t{%40d,", symbol_prefix, table[0]); 722 723 j = 10; 724 for (i = 1; i <= high; i++) { 725 if (j >= 10) { 726 if (!rflag) 727 ++outline; 728 putc('\n', output_file); 729 j = 1; 730 } else 731 ++j; 732 fprintf(output_file, "%5d,", table[i]); 733 } 734 735 if (!rflag) 736 outline += 2; 737 fprintf(output_file, "\n};\n"); 738 free(table); 739 } 740 741 742 void 743 output_check(void) 744 { 745 int i, j; 746 747 fprintf(output_file, "const short %scheck[] =\n" 748 "\t{%40d,", symbol_prefix, check[0]); 749 750 j = 10; 751 for (i = 1; i <= high; i++) { 752 if (j >= 10) { 753 if (!rflag) 754 ++outline; 755 putc('\n', output_file); 756 j = 1; 757 } else 758 ++j; 759 fprintf(output_file, "%5d,", check[i]); 760 } 761 762 if (!rflag) 763 outline += 2; 764 fprintf(output_file, "\n};\n"); 765 free(check); 766 } 767 768 769 int 770 is_C_identifier(char *name) 771 { 772 char *s; 773 int c; 774 775 s = name; 776 c = (unsigned char)*s; 777 if (c == '"') { 778 c = (unsigned char)*++s; 779 if (!isalpha(c) && c != '_' && c != '$') 780 return (0); 781 while ((c = (unsigned char)*++s) != '"') { 782 if (!isalnum(c) && c != '_' && c != '$') 783 return (0); 784 } 785 return (1); 786 } 787 788 if (!isalpha(c) && c != '_' && c != '$') 789 return (0); 790 while ((c = (unsigned char)*++s)) { 791 if (!isalnum(c) && c != '_' && c != '$') 792 return (0); 793 } 794 return (1); 795 } 796 797 798 void 799 output_defines(void) 800 { 801 int c, i; 802 char *s; 803 804 for (i = 2; i < ntokens; ++i) { 805 s = symbol_name[i]; 806 if (is_C_identifier(s)) { 807 fprintf(code_file, "#define "); 808 if (dflag) 809 fprintf(defines_file, "#define "); 810 c = (unsigned char)*s; 811 if (c == '"') { 812 while ((c = (unsigned char)*++s) != '"') { 813 putc(c, code_file); 814 if (dflag) 815 putc(c, defines_file); 816 } 817 } else { 818 do { 819 putc(c, code_file); 820 if (dflag) 821 putc(c, defines_file); 822 } while ((c = (unsigned char)*++s)); 823 } 824 ++outline; 825 fprintf(code_file, " %d\n", symbol_value[i]); 826 if (dflag) 827 fprintf(defines_file, " %d\n", symbol_value[i]); 828 } 829 } 830 831 ++outline; 832 fprintf(code_file, "#define YYERRCODE %d\n", symbol_value[1]); 833 834 if (dflag && unionized) { 835 fclose(union_file); 836 union_file = fopen(union_file_name, "r"); 837 if (union_file == NULL) 838 open_error(union_file_name); 839 while ((c = getc(union_file)) != EOF) 840 putc(c, defines_file); 841 fprintf(defines_file, " YYSTYPE;\n"); 842 fprintf(defines_file, "#endif /* YYSTYPE_DEFINED */\n"); 843 fprintf(defines_file, "extern YYSTYPE %slval;\n", 844 symbol_prefix); 845 } 846 } 847 848 849 void 850 output_stored_text(void) 851 { 852 int c; 853 FILE *in, *out; 854 855 fclose(text_file); 856 text_file = fopen(text_file_name, "r"); 857 if (text_file == NULL) 858 open_error(text_file_name); 859 in = text_file; 860 if ((c = getc(in)) == EOF) 861 return; 862 out = code_file; 863 if (c == '\n') 864 ++outline; 865 putc(c, out); 866 while ((c = getc(in)) != EOF) { 867 if (c == '\n') 868 ++outline; 869 putc(c, out); 870 } 871 if (!lflag) 872 fprintf(out, line_format, ++outline + 1, code_file_name); 873 } 874 875 876 void 877 output_debug(void) 878 { 879 int i, j, k, max; 880 char **symnam, *s; 881 882 ++outline; 883 fprintf(code_file, "#define YYFINAL %d\n", final_state); 884 outline += 3; 885 fprintf(code_file, "#ifndef YYDEBUG\n#define YYDEBUG %d\n#endif\n", 886 tflag); 887 if (rflag) 888 fprintf(output_file, "#ifndef YYDEBUG\n#define YYDEBUG %d\n#endif\n", 889 tflag); 890 891 max = 0; 892 for (i = 2; i < ntokens; ++i) 893 if (symbol_value[i] > max) 894 max = symbol_value[i]; 895 ++outline; 896 fprintf(code_file, "#define YYMAXTOKEN %d\n", max); 897 898 symnam = calloc(max+1, sizeof(char *)); 899 if (symnam == NULL) 900 no_space(); 901 902 for (i = ntokens - 1; i >= 2; --i) 903 symnam[symbol_value[i]] = symbol_name[i]; 904 symnam[0] = "end-of-file"; 905 906 if (!rflag) 907 ++outline; 908 fprintf(output_file, 909 "#if YYDEBUG\n" 910 "const char * const %sname[] =\n" 911 "\t{", symbol_prefix); 912 j = 80; 913 for (i = 0; i <= max; ++i) { 914 if ((s = symnam[i]) != '\0') { 915 if (s[0] == '"') { 916 k = 7; 917 while (*++s != '"') { 918 ++k; 919 if (*s == '\\') { 920 k += 2; 921 if (*++s == '\\') 922 ++k; 923 } 924 } 925 j += k; 926 if (j > 80) { 927 if (!rflag) 928 ++outline; 929 putc('\n', output_file); 930 j = k; 931 } 932 fprintf(output_file, "\"\\\""); 933 s = symnam[i]; 934 while (*++s != '"') { 935 if (*s == '\\') { 936 fprintf(output_file, "\\\\"); 937 if (*++s == '\\') 938 fprintf(output_file, "\\\\"); 939 else 940 putc(*s, output_file); 941 } else 942 putc(*s, output_file); 943 } 944 fprintf(output_file, "\\\"\","); 945 } else if (s[0] == '\'') { 946 if (s[1] == '"') { 947 j += 7; 948 if (j > 80) { 949 if (!rflag) 950 ++outline; 951 putc('\n', output_file); 952 j = 7; 953 } 954 fprintf(output_file, "\"'\\\"'\","); 955 } else { 956 k = 5; 957 while (*++s != '\'') { 958 ++k; 959 if (*s == '\\') { 960 k += 2; 961 if (*++s == '\\') 962 ++k; 963 } 964 } 965 j += k; 966 if (j > 80) { 967 if (!rflag) 968 ++outline; 969 putc('\n', output_file); 970 j = k; 971 } 972 fprintf(output_file, "\"'"); 973 s = symnam[i]; 974 while (*++s != '\'') { 975 if (*s == '\\') { 976 fprintf(output_file, "\\\\"); 977 if (*++s == '\\') 978 fprintf(output_file, "\\\\"); 979 else 980 putc(*s, output_file); 981 } else 982 putc(*s, output_file); 983 } 984 fprintf(output_file, "'\","); 985 } 986 } else { 987 k = strlen(s) + 3; 988 j += k; 989 if (j > 80) { 990 if (!rflag) 991 ++outline; 992 putc('\n', output_file); 993 j = k; 994 } 995 putc('"', output_file); 996 do { 997 putc(*s, output_file); 998 } while (*++s); 999 fprintf(output_file, "\","); 1000 } 1001 } else { 1002 j += 2; 1003 if (j > 80) { 1004 if (!rflag) 1005 ++outline; 1006 putc('\n', output_file); 1007 j = 2; 1008 } 1009 fprintf(output_file, "0,"); 1010 } 1011 } 1012 if (!rflag) 1013 outline += 2; 1014 fprintf(output_file, "\n};\n"); 1015 free(symnam); 1016 1017 if (!rflag) 1018 ++outline; 1019 fprintf(output_file, 1020 "const char * const %srule[] =\n" 1021 "\t{", symbol_prefix); 1022 for (i = 2; i < nrules; ++i) { 1023 fprintf(output_file, "\"%s :", symbol_name[rlhs[i]]); 1024 for (j = rrhs[i]; ritem[j] > 0; ++j) { 1025 s = symbol_name[ritem[j]]; 1026 if (s[0] == '"') { 1027 fprintf(output_file, " \\\""); 1028 while (*++s != '"') { 1029 if (*s == '\\') { 1030 if (s[1] == '\\') 1031 fprintf(output_file, "\\\\\\\\"); 1032 else 1033 fprintf(output_file, "\\\\%c", s[1]); 1034 ++s; 1035 } else 1036 putc(*s, output_file); 1037 } 1038 fprintf(output_file, "\\\""); 1039 } else if (s[0] == '\'') { 1040 if (s[1] == '"') 1041 fprintf(output_file, " '\\\"'"); 1042 else if (s[1] == '\\') { 1043 if (s[2] == '\\') 1044 fprintf(output_file, " '\\\\\\\\"); 1045 else 1046 fprintf(output_file, " '\\\\%c", s[2]); 1047 s += 2; 1048 while (*++s != '\'') 1049 putc(*s, output_file); 1050 putc('\'', output_file); 1051 } else 1052 fprintf(output_file, " '%c'", s[1]); 1053 } else 1054 fprintf(output_file, " %s", s); 1055 } 1056 if (!rflag) 1057 ++outline; 1058 fprintf(output_file, "\",\n"); 1059 } 1060 1061 if (!rflag) 1062 outline += 2; 1063 fprintf(output_file, "};\n#endif\n"); 1064 } 1065 1066 1067 void 1068 output_stype(void) 1069 { 1070 if (!unionized && ntags == 0) { 1071 outline += 3; 1072 fprintf(code_file, "#ifndef YYSTYPE\ntypedef int YYSTYPE;\n#endif\n"); 1073 } 1074 } 1075 1076 1077 void 1078 output_trailing_text(void) 1079 { 1080 int c, last; 1081 FILE *in, *out; 1082 1083 if (line == 0) 1084 return; 1085 1086 in = input_file; 1087 out = code_file; 1088 c = (unsigned char)*cptr; 1089 if (c == '\n') { 1090 ++lineno; 1091 if ((c = getc(in)) == EOF) 1092 return; 1093 if (!lflag) { 1094 ++outline; 1095 fprintf(out, line_format, lineno, input_file_name); 1096 } 1097 if (c == '\n') 1098 ++outline; 1099 putc(c, out); 1100 last = c; 1101 } else { 1102 if (!lflag) { 1103 ++outline; 1104 fprintf(out, line_format, lineno, input_file_name); 1105 } 1106 do { 1107 putc(c, out); 1108 } while ((c = (unsigned char)*++cptr) != '\n'); 1109 ++outline; 1110 putc('\n', out); 1111 last = '\n'; 1112 } 1113 1114 while ((c = getc(in)) != EOF) { 1115 if (c == '\n') 1116 ++outline; 1117 putc(c, out); 1118 last = c; 1119 } 1120 1121 if (last != '\n') { 1122 ++outline; 1123 putc('\n', out); 1124 } 1125 if (!lflag) 1126 fprintf(out, line_format, ++outline + 1, code_file_name); 1127 } 1128 1129 1130 void 1131 output_semantic_actions(void) 1132 { 1133 int c, last; 1134 FILE *out; 1135 1136 fclose(action_file); 1137 action_file = fopen(action_file_name, "r"); 1138 if (action_file == NULL) 1139 open_error(action_file_name); 1140 1141 if ((c = getc(action_file)) == EOF) 1142 return; 1143 1144 out = code_file; 1145 last = c; 1146 if (c == '\n') 1147 ++outline; 1148 putc(c, out); 1149 while ((c = getc(action_file)) != EOF) { 1150 if (c == '\n') 1151 ++outline; 1152 putc(c, out); 1153 last = c; 1154 } 1155 1156 if (last != '\n') { 1157 ++outline; 1158 putc('\n', out); 1159 } 1160 1161 if (!lflag) 1162 fprintf(out, line_format, ++outline + 1, code_file_name); 1163 } 1164 1165 1166 void 1167 free_itemsets(void) 1168 { 1169 core *cp, *next; 1170 1171 free(state_table); 1172 for (cp = first_state; cp; cp = next) { 1173 next = cp->next; 1174 free(cp); 1175 } 1176 } 1177 1178 1179 void 1180 free_shifts(void) 1181 { 1182 shifts *sp, *next; 1183 1184 free(shift_table); 1185 for (sp = first_shift; sp; sp = next) { 1186 next = sp->next; 1187 free(sp); 1188 } 1189 } 1190 1191 1192 1193 void 1194 free_reductions(void) 1195 { 1196 reductions *rp, *next; 1197 1198 free(reduction_table); 1199 for (rp = first_reduction; rp; rp = next) { 1200 next = rp->next; 1201 free(rp); 1202 } 1203 } 1204