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