1 %{ 2 #include "cc.h" 3 %} 4 %union { 5 Node* node; 6 Sym* sym; 7 Type* type; 8 struct 9 { 10 Type* t; 11 char c; 12 } tycl; 13 struct 14 { 15 Type* t1; 16 Type* t2; 17 } tyty; 18 struct 19 { 20 char* s; 21 long l; 22 } sval; 23 long lval; 24 double dval; 25 vlong vval; 26 } 27 %type <sym> ltag 28 %type <lval> gctname cname gname tname 29 %type <lval> gctnlist zgnlist tnlist 30 %type <type> tlist etlist sbody complex 31 %type <tycl> types etypes 32 %type <node> zarglist arglist zcexpr 33 %type <node> name block stmnt cexpr expr xuexpr pexpr 34 %type <node> zelist elist adecl slist uexpr string lstring sstring slstring 35 %type <node> xdecor xdecor2 labels label ulstmnt 36 %type <node> adlist edecor tag qual qlist 37 %type <node> abdecor abdecor1 abdecor2 abdecor3 38 %type <node> zexpr lexpr init ilist 39 40 %left ';' 41 %left ',' 42 %right '=' LPE LME LMLE LDVE LMDE LRSHE LLSHE LANDE LXORE LORE 43 %right '?' ':' 44 %left LOROR 45 %left LANDAND 46 %left '|' 47 %left '^' 48 %left '&' 49 %left LEQ LNE 50 %left '<' '>' LLE LGE 51 %left LLSH LRSH 52 %left '+' '-' 53 %left '*' '/' '%' 54 %right LMM LPP LMG '.' '[' '(' 55 56 %token <sym> LNAME LCTYPE LSTYPE 57 %token <dval> LFCONST LDCONST 58 %token <vval> LCHARACTER LCONST LLCONST LUCONST LULCONST LVLCONST LUVLCONST 59 %token <sval> LSTRING LLSTRING 60 %token LAUTO LBREAK LCASE LCHAR LCONTINUE LDEFAULT LDO 61 %token LDOUBLE LELSE LEXTERN LFLOAT LFOR LGOTO 62 %token LIF LINT LLONG LREGISTER LRETURN LSHORT LSIZEOF LUSED 63 %token LSTATIC LSTRUCT LSWITCH LTYPEDEF LUNION LUNSIGNED LWHILE 64 %token LVOID LENUM LSIGNED LCONSTNT LVOLATILE LSET LSIGNOF LVLONG 65 %% 66 prog: 67 | prog xdecl 68 69 /* 70 * external declarator 71 */ 72 xdecl: 73 zctlist ';' 74 { 75 dodecl(xdecl, lastclass, lasttype, Z, 1); 76 } 77 | zctlist xdlist ';' 78 | zctlist xdecor 79 { 80 lastdcl = T; 81 dodecl(xdecl, lastclass, lasttype, $2, 0); 82 if(lastdcl == T || lastdcl->etype != TFUNC) { 83 diag($2, "not a function"); 84 lastdcl = types[TFUNC]; 85 } 86 thisfn = lastdcl; 87 markdcl(); 88 firstdcl = dclstack; 89 argmark($2, 0); 90 } 91 pdecl 92 { 93 argmark($2, 1); 94 } 95 block 96 { 97 $6->blk = 0; 98 codgen($6, $2, lineno); 99 revertdcl(); 100 } 101 102 xdlist: 103 xdecor 104 { 105 dodecl(xdecl, lastclass, lasttype, $1, 1); 106 } 107 | xdecor 108 { 109 $1 = dodecl(xdecl, lastclass, lasttype, $1, 0); 110 } 111 '=' init 112 { 113 $4 = doinit($1->sym, $1->type, 0L, $4); 114 $4 = new(ODAS, $1, $4); 115 $4->type = $1->type; 116 $4->lineno = $1->lineno; 117 vtgen($4); 118 } 119 | xdlist ',' xdlist 120 121 xdecor: 122 xdecor2 123 | '*' zgnlist xdecor 124 { 125 $$ = new(OIND, $3, Z); 126 $$->garb = simpleg($2); 127 } 128 129 xdecor2: 130 tag 131 | '(' xdecor ')' 132 { 133 $$ = $2; 134 } 135 | xdecor2 '(' zarglist ')' 136 { 137 $$ = new(OFUNC, $1, $3); 138 /* outfun($$); */ 139 } 140 | xdecor2 '[' zexpr ']' 141 { 142 $$ = new(OARRAY, $1, $3); 143 } 144 145 /* 146 * automatic declarator 147 */ 148 adecl: 149 { 150 $$ = Z; 151 } 152 | adecl ctlist ';' 153 { 154 $$ = dodecl(adecl, lastclass, lasttype, Z, 1); 155 if($1 != Z) 156 if($$ != Z) 157 $$ = new(OLIST, $1, $$); 158 else 159 $$ = $1; 160 } 161 | adecl ctlist adlist ';' 162 { 163 $$ = $1; 164 if($3 != Z) { 165 $$ = $3; 166 if($1 != Z) 167 $$ = new(OLIST, $1, $3); 168 } 169 } 170 171 adlist: 172 xdecor 173 { 174 $$ = dodecl(adecl, lastclass, lasttype, $1, 1); 175 if($$->sym->class == CSTATIC) 176 $$ = Z; 177 } 178 | xdecor 179 { 180 $1 = dodecl(adecl, lastclass, lasttype, $1, 0); 181 } 182 '=' init 183 { 184 /* long w; */ 185 186 /* w = $1->sym->type->width; */ 187 $$ = doinit($1->sym, $1->type, 0L, $4); 188 /* $$ = contig($1->sym, $$, w); */ 189 $$ = new(ODAS, $1, $$); 190 $$->type = $1->type; 191 $$->lineno = $1->lineno; 192 vtgen($$); 193 if($1->sym->class == CSTATIC) 194 $$ = Z; 195 } 196 | adlist ',' adlist 197 { 198 $$ = $1; 199 if($3 != Z) { 200 $$ = $3; 201 if($1 != Z) 202 $$ = new(OLIST, $1, $3); 203 } 204 } 205 206 /* 207 * parameter declarator 208 */ 209 pdecl: 210 | pdecl ctlist pdlist ';' 211 212 pdlist: 213 xdecor 214 { 215 dodecl(pdecl, lastclass, lasttype, $1, 1); 216 } 217 | pdlist ',' pdlist 218 219 /* 220 * structure element declarator 221 */ 222 edecl: 223 etlist 224 { 225 lasttype = $1; 226 } 227 zedlist ';' 228 | edecl etlist 229 { 230 lasttype = $2; 231 } 232 zedlist ';' 233 234 zedlist: /* extension */ 235 { 236 lastfield = 0; 237 edecl(CXXX, lasttype, S); 238 } 239 | edlist 240 241 edlist: 242 edecor 243 { 244 dodecl(edecl, CXXX, lasttype, $1, 1); 245 } 246 | edlist ',' edlist 247 248 edecor: 249 xdecor 250 { 251 lastbit = 0; 252 firstbit = 1; 253 } 254 | tag ':' lexpr 255 { 256 $$ = new(OBIT, $1, $3); 257 } 258 | ':' lexpr 259 { 260 $$ = new(OBIT, Z, $2); 261 } 262 263 /* 264 * abstract declarator 265 */ 266 abdecor: 267 { 268 $$ = (Z); 269 } 270 | abdecor1 271 272 abdecor1: 273 '*' zgnlist 274 { 275 $$ = new(OIND, (Z), Z); 276 $$->garb = simpleg($2); 277 } 278 | '*' zgnlist abdecor1 279 { 280 $$ = new(OIND, $3, Z); 281 $$->garb = simpleg($2); 282 } 283 | abdecor2 284 285 abdecor2: 286 abdecor3 287 | abdecor2 '(' zarglist ')' 288 { 289 $$ = new(OFUNC, $1, $3); 290 } 291 | abdecor2 '[' zexpr ']' 292 { 293 $$ = new(OARRAY, $1, $3); 294 } 295 296 abdecor3: 297 '(' ')' 298 { 299 $$ = new(OFUNC, (Z), Z); 300 } 301 | '[' zexpr ']' 302 { 303 $$ = new(OARRAY, (Z), $2); 304 } 305 | '(' abdecor1 ')' 306 { 307 $$ = $2; 308 } 309 310 init: 311 expr 312 | '{' ilist '}' 313 { 314 $$ = new(OINIT, invert($2), Z); 315 } 316 317 qual: 318 '[' lexpr ']' 319 { 320 $$ = new(OARRAY, $2, Z); 321 } 322 | '.' ltag 323 { 324 $$ = new(OELEM, Z, Z); 325 $$->sym = $2; 326 } 327 | qual '=' 328 329 qlist: 330 init ',' 331 | qlist init ',' 332 { 333 $$ = new(OLIST, $1, $2); 334 } 335 | qual 336 | qlist qual 337 { 338 $$ = new(OLIST, $1, $2); 339 } 340 341 ilist: 342 qlist 343 | init 344 | qlist init 345 { 346 $$ = new(OLIST, $1, $2); 347 } 348 349 zarglist: 350 { 351 $$ = Z; 352 } 353 | arglist 354 { 355 $$ = invert($1); 356 } 357 358 359 arglist: 360 name 361 | tlist abdecor 362 { 363 $$ = new(OPROTO, $2, Z); 364 $$->type = $1; 365 } 366 | tlist xdecor 367 { 368 $$ = new(OPROTO, $2, Z); 369 $$->type = $1; 370 } 371 | '.' '.' '.' 372 { 373 $$ = new(ODOTDOT, Z, Z); 374 } 375 | arglist ',' arglist 376 { 377 $$ = new(OLIST, $1, $3); 378 } 379 380 block: 381 '{' adecl slist '}' 382 { 383 $$ = invert($3); 384 if($2 != Z) 385 $$ = new(OLIST, $2, $$); 386 if($$ == Z) 387 $$ = new(ONUL, Z, Z); 388 $$->blk = 1; 389 } 390 391 slist: 392 { 393 $$ = Z; 394 } 395 | slist stmnt 396 { 397 if($1 == Z) 398 $$ = $2; 399 else 400 $$ = new(OLIST, $1, $2); 401 } 402 403 labels: 404 label 405 | labels label 406 { 407 $$ = new(OLIST, $1, $2); 408 } 409 410 label: 411 LCASE expr ':' 412 { 413 $$ = new(OCASE, $2, Z); 414 $$->lineno = $2->lineno; 415 } 416 | LDEFAULT ':' 417 { 418 $$ = new(OCASE, Z, Z); 419 } 420 | LNAME ':' 421 { 422 $$ = new(OLABEL, dcllabel($1, 1), Z); 423 $1->lineno = lineno; 424 } 425 426 stmnt: 427 error ';' 428 { 429 $$ = Z; 430 } 431 | ulstmnt 432 | labels ulstmnt 433 { 434 $$ = new(OLIST, $1, $2); 435 } 436 437 ulstmnt: 438 zcexpr ';' 439 { 440 if($$ == Z) 441 $$ = new(ONUL, Z, Z); 442 $$->kind = KEXP; 443 } 444 | { 445 markdcl(); 446 } 447 block 448 { 449 revertdcl(); 450 $$ = $2; 451 } 452 | LIF '(' cexpr ')' stmnt 453 { 454 $$ = new(OIF, $3, new(OLIST, $5, Z)); 455 $$->lineno = $3->lineno; 456 $5->blk = 0; 457 } 458 | LIF '(' cexpr ')' stmnt LELSE stmnt 459 { 460 $$ = new(OIF, $3, new(OLIST, $5, $7)); 461 $$->lineno = $3->lineno; 462 $5->blk = $7->blk = 0; 463 } 464 | LFOR '(' zcexpr ';' zcexpr ';' zcexpr ')' stmnt 465 { 466 $$ = new(OFOR, new(OLIST, $5, new(OLIST, $3, $7)), $9); 467 if($3 != Z) 468 $$->lineno = $3->lineno; 469 else if($5 != Z) 470 $$->lineno = $5->lineno; 471 else if($7 != Z) 472 $$->lineno = $7->lineno; 473 else 474 $$->lineno = line($9); 475 $9->blk = 0; 476 } 477 | LWHILE '(' cexpr ')' stmnt 478 { 479 $$ = new(OWHILE, $3, $5); 480 $$->lineno = $3->lineno; 481 $5->blk = 0; 482 } 483 | LDO stmnt LWHILE '(' cexpr ')' ';' 484 { 485 $$ = new(ODWHILE, $5, $2); 486 $$->lineno = line($2); 487 $2->blk = 0; 488 } 489 | LRETURN zcexpr ';' 490 { 491 $$ = new(ORETURN, $2, Z); 492 $$->type = thisfn->link; 493 if($2 != Z) 494 $$->lineno = $2->lineno; 495 } 496 | LSWITCH '(' cexpr ')' stmnt 497 { 498 $$ = new(OSWITCH, $3, $5); 499 $$->lineno = $3->lineno; 500 $5->blk = 0; 501 } 502 | LBREAK ';' 503 { 504 $$ = new(OBREAK, Z, Z); 505 } 506 | LCONTINUE ';' 507 { 508 $$ = new(OCONTINUE, Z, Z); 509 } 510 | LGOTO LNAME ';' 511 { 512 $$ = new(OGOTO, dcllabel($2, 0), Z); 513 $2->lineno = lineno; 514 } 515 | LUSED '(' zelist ')' ';' 516 { 517 $$ = new(OUSED, $3, Z); 518 $$->lineno = line($3); 519 } 520 | LSET '(' zelist ')' ';' 521 { 522 $$ = new(OSET, $3, Z); 523 $$->lineno = line($3); 524 } 525 526 zcexpr: 527 { 528 $$ = Z; 529 } 530 | cexpr 531 532 zexpr: 533 { 534 $$ = Z; 535 } 536 | lexpr 537 538 lexpr: 539 expr 540 { 541 $$ = new(OCAST, $1, Z); 542 $$->type = types[TLONG]; 543 } 544 545 cexpr: 546 expr 547 | cexpr ',' cexpr 548 { 549 $$ = new(OCOMMA, $1, $3); 550 } 551 552 expr: 553 xuexpr 554 | expr '*' expr 555 { 556 $$ = new(OMUL, $1, $3); 557 } 558 | expr '/' expr 559 { 560 $$ = new(ODIV, $1, $3); 561 } 562 | expr '%' expr 563 { 564 $$ = new(OMOD, $1, $3); 565 } 566 | expr '+' expr 567 { 568 $$ = new(OADD, $1, $3); 569 } 570 | expr '-' expr 571 { 572 $$ = new(OSUB, $1, $3); 573 } 574 | expr LRSH expr 575 { 576 $$ = new(OASHR, $1, $3); 577 } 578 | expr LLSH expr 579 { 580 $$ = new(OASHL, $1, $3); 581 } 582 | expr '<' expr 583 { 584 $$ = new(OLT, $1, $3); 585 } 586 | expr '>' expr 587 { 588 $$ = new(OGT, $1, $3); 589 } 590 | expr LLE expr 591 { 592 $$ = new(OLE, $1, $3); 593 } 594 | expr LGE expr 595 { 596 $$ = new(OGE, $1, $3); 597 } 598 | expr LEQ expr 599 { 600 $$ = new(OEQ, $1, $3); 601 } 602 | expr LNE expr 603 { 604 $$ = new(ONE, $1, $3); 605 } 606 | expr '&' expr 607 { 608 $$ = new(OAND, $1, $3); 609 } 610 | expr '^' expr 611 { 612 $$ = new(OXOR, $1, $3); 613 } 614 | expr '|' expr 615 { 616 $$ = new(OOR, $1, $3); 617 } 618 | expr LANDAND expr 619 { 620 $$ = new(OANDAND, $1, $3); 621 } 622 | expr LOROR expr 623 { 624 $$ = new(OOROR, $1, $3); 625 } 626 | expr '?' cexpr ':' expr 627 { 628 $$ = new(OCOND, $1, new(OLIST, $3, $5)); 629 } 630 | expr '=' expr 631 { 632 $$ = new(OAS, $1, $3); 633 } 634 | expr LPE expr 635 { 636 $$ = new(OASADD, $1, $3); 637 } 638 | expr LME expr 639 { 640 $$ = new(OASSUB, $1, $3); 641 } 642 | expr LMLE expr 643 { 644 $$ = new(OASMUL, $1, $3); 645 } 646 | expr LDVE expr 647 { 648 $$ = new(OASDIV, $1, $3); 649 } 650 | expr LMDE expr 651 { 652 $$ = new(OASMOD, $1, $3); 653 } 654 | expr LLSHE expr 655 { 656 $$ = new(OASASHL, $1, $3); 657 } 658 | expr LRSHE expr 659 { 660 $$ = new(OASASHR, $1, $3); 661 } 662 | expr LANDE expr 663 { 664 $$ = new(OASAND, $1, $3); 665 } 666 | expr LXORE expr 667 { 668 $$ = new(OASXOR, $1, $3); 669 } 670 | expr LORE expr 671 { 672 $$ = new(OASOR, $1, $3); 673 } 674 675 xuexpr: 676 uexpr 677 | '(' tlist abdecor ')' xuexpr 678 { 679 $$ = new(OCAST, $5, Z); 680 dodecl(NODECL, CXXX, $2, $3, 1); 681 $$->type = lastdcl; 682 } 683 | '(' tlist abdecor ')' '{' ilist '}' /* extension */ 684 { 685 $$ = new(OSTRUCT, $6, Z); 686 dodecl(NODECL, CXXX, $2, $3, 1); 687 $$->type = lastdcl; 688 } 689 690 uexpr: 691 pexpr 692 | '*' xuexpr 693 { 694 $$ = new(OIND, $2, Z); 695 } 696 | '&' xuexpr 697 { 698 $$ = new(OADDR, $2, Z); 699 } 700 | '+' xuexpr 701 { 702 $$ = new(OPOS, $2, Z); 703 } 704 | '-' xuexpr 705 { 706 $$ = new(ONEG, $2, Z); 707 } 708 | '!' xuexpr 709 { 710 $$ = new(ONOT, $2, Z); 711 } 712 | '~' xuexpr 713 { 714 $$ = new(OCOM, $2, Z); 715 } 716 | LPP xuexpr 717 { 718 $$ = new(OPREINC, $2, Z); 719 } 720 | LMM xuexpr 721 { 722 $$ = new(OPREDEC, $2, Z); 723 } 724 | LSIZEOF uexpr 725 { 726 $$ = new(OSIZE, $2, Z); 727 } 728 | LSIGNOF uexpr 729 { 730 $$ = new(OSIGN, $2, Z); 731 } 732 733 pexpr: 734 '(' cexpr ')' 735 { 736 $$ = $2; 737 } 738 | LSIZEOF '(' tlist abdecor ')' 739 { 740 $$ = new(OSIZE, Z, Z); 741 dodecl(NODECL, CXXX, $3, $4, 1); 742 $$->type = lastdcl; 743 } 744 | LSIGNOF '(' tlist abdecor ')' 745 { 746 $$ = new(OSIGN, Z, Z); 747 dodecl(NODECL, CXXX, $3, $4, 1); 748 $$->type = lastdcl; 749 } 750 | pexpr '(' zelist ')' 751 { 752 $$ = new(OFUNC, $1, Z); 753 if($1->op == ONAME) 754 if($1->type == T) 755 dodecl(xdecl, CXXX, types[TINT], $$, 1); 756 $$->right = invert($3); 757 $$->kind = KEXP; 758 } 759 | pexpr '[' cexpr ']' 760 { 761 $$ = new(OARRIND, $1, $3); 762 } 763 | pexpr LMG ltag 764 { 765 $$ = new(ODOTIND, $1, Z); 766 $$->sym = $3; 767 } 768 | pexpr '.' ltag 769 { 770 $$ = new(ODOT, $1, Z); 771 $$->sym = $3; 772 } 773 | pexpr LPP 774 { 775 $$ = new(OPOSTINC, $1, Z); 776 } 777 | pexpr LMM 778 { 779 $$ = new(OPOSTDEC, $1, Z); 780 } 781 | name 782 | LCHARACTER 783 { 784 $$ = new(OCONST, Z, Z); 785 $$->type = types[TINT]; 786 $$->vconst = $1; 787 $$->kind = KCHR; 788 } 789 | LCONST 790 { 791 $$ = new(OCONST, Z, Z); 792 $$->type = types[TINT]; 793 $$->vconst = $1; 794 $$->kind = lastnumbase; 795 } 796 | LLCONST 797 { 798 $$ = new(OCONST, Z, Z); 799 $$->type = types[TLONG]; 800 $$->vconst = $1; 801 $$->kind = lastnumbase; 802 } 803 | LUCONST 804 { 805 $$ = new(OCONST, Z, Z); 806 $$->type = types[TUINT]; 807 $$->vconst = $1; 808 $$->kind = lastnumbase; 809 } 810 | LULCONST 811 { 812 $$ = new(OCONST, Z, Z); 813 $$->type = types[TULONG]; 814 $$->vconst = $1; 815 $$->kind = lastnumbase; 816 } 817 | LDCONST 818 { 819 $$ = new(OCONST, Z, Z); 820 $$->type = types[TDOUBLE]; 821 $$->fconst = $1; 822 $$->cstring = strdup(symb); 823 $$->kind = lastnumbase; 824 } 825 | LFCONST 826 { 827 $$ = new(OCONST, Z, Z); 828 $$->type = types[TFLOAT]; 829 $$->fconst = $1; 830 $$->cstring = strdup(symb); 831 $$->kind = lastnumbase; 832 } 833 | LVLCONST 834 { 835 $$ = new(OCONST, Z, Z); 836 $$->type = types[TVLONG]; 837 $$->vconst = $1; 838 $$->kind = lastnumbase; 839 } 840 | LUVLCONST 841 { 842 $$ = new(OCONST, Z, Z); 843 $$->type = types[TUVLONG]; 844 $$->vconst = $1; 845 $$->kind = lastnumbase; 846 } 847 | string 848 | lstring 849 850 sstring: 851 LSTRING 852 { 853 $$ = new(OSTRING, Z, Z); 854 $$->type = typ(TARRAY, types[TCHAR]); 855 $$->type->width = $1.l + 1; 856 $$->cstring = $1.s; 857 $$->sym = symstring; 858 } 859 860 string: 861 sstring 862 { 863 $$ = $1; 864 } 865 | string sstring 866 { 867 char *s; 868 int n1, n2; 869 870 n1 = $1->type->width - 1; 871 n2 = $2->type->width - 1; 872 s = alloc(n1+n2+MAXALIGN); 873 874 memcpy(s, $1->cstring, n1); 875 memcpy(s+n1, $2->cstring, n2); 876 s[n1+n2] = 0; 877 878 $1->left = new(OCAT, ncopy($1), $2); 879 880 $$ = $1; 881 $$->type->width += n2; 882 $$->cstring = s; 883 } 884 885 slstring: 886 LLSTRING 887 { 888 $$ = new(OLSTRING, Z, Z); 889 $$->type = typ(TARRAY, types[TUSHORT]); 890 $$->type->width = $1.l + sizeof(TRune); 891 $$->rstring = (TRune*)$1.s; 892 $$->sym = symstring; 893 } 894 895 lstring: 896 slstring 897 { 898 $$ = $1; 899 } 900 | lstring slstring 901 { 902 char *s; 903 int n1, n2; 904 905 n1 = $1->type->width - sizeof(TRune); 906 n2 = $2->type->width - sizeof(TRune); 907 s = alloc(n1+n2+MAXALIGN); 908 909 memcpy(s, $1->rstring, n1); 910 memcpy(s+n1, $2->rstring, n2); 911 *(TRune*)(s+n1+n2) = 0; 912 913 $1->left = new(OCAT, ncopy($1), $2); 914 915 $$ = $1; 916 $$->type->width += n2; 917 $$->rstring = (TRune*)s; 918 } 919 920 zelist: 921 { 922 $$ = Z; 923 } 924 | elist 925 926 elist: 927 expr 928 | elist ',' elist 929 { 930 $$ = new(OLIST, $1, $3); 931 } 932 933 sbody: 934 '{' 935 { 936 $<tyty>$.t1 = strf; 937 $<tyty>$.t2 = strl; 938 strf = T; 939 strl = T; 940 lastbit = 0; 941 firstbit = 1; 942 } 943 edecl '}' 944 { 945 $$ = strf; 946 strf = $<tyty>2.t1; 947 strl = $<tyty>2.t2; 948 } 949 950 zctlist: 951 { 952 lastclass = CXXX; 953 lasttype = types[TINT]; 954 } 955 | ctlist 956 957 etypes: 958 complex 959 { 960 $$.t = $1; 961 $$.c = CXXX; 962 } 963 | tnlist 964 { 965 $$.t = simplet($1); 966 $$.c = simplec($1); 967 } 968 969 types: 970 complex 971 { 972 $$.t = $1; 973 $$.c = CXXX; 974 } 975 | complex gctnlist 976 { 977 $$.t = $1; 978 $$.c = simplec($2); 979 if($2 & ~BCLASS & ~BGARB) 980 diag(Z, "illegal combination of types 1: %Q/%T", $2, $1); 981 } 982 | gctnlist 983 { 984 $$.t = simplet($1); 985 $$.c = simplec($1); 986 $$.t = garbt($$.t, $1); 987 } 988 | gctnlist complex 989 { 990 $$.t = $2; 991 $$.c = simplec($1); 992 $$.t = garbt($$.t, $1); 993 if($1 & ~BCLASS & ~BGARB) 994 diag(Z, "illegal combination of types 2: %Q/%T", $1, $2); 995 } 996 | gctnlist complex gctnlist 997 { 998 $$.t = $2; 999 $$.c = simplec($1|$3); 1000 $$.t = garbt($$.t, $1|$3); 1001 if(($1|$3) & ~BCLASS & ~BGARB || $3 & BCLASS) 1002 diag(Z, "illegal combination of types 3: %Q/%T/%Q", $1, $2, $3); 1003 } 1004 1005 etlist: 1006 zgnlist etypes 1007 { 1008 $$ = $2.t; 1009 if($2.c != CXXX) 1010 diag(Z, "illegal combination of class 4: %s", cnames[$2.c]); 1011 $$ = garbt($$, $1); 1012 } 1013 1014 tlist: 1015 types 1016 { 1017 $$ = $1.t; 1018 if($1.c != CXXX) 1019 diag(Z, "illegal combination of class 4: %s", cnames[$1.c]); 1020 } 1021 1022 ctlist: 1023 types 1024 { 1025 lasttype = $1.t; 1026 lastclass = $1.c; 1027 } 1028 1029 complex: 1030 LSTRUCT ltag 1031 { 1032 dotag($2, TSTRUCT, 0); 1033 $$ = $2->suetag; 1034 $2->lineno = lineno; 1035 } 1036 | LSTRUCT ltag 1037 { 1038 dotag($2, TSTRUCT, autobn); 1039 saveline = $2->lineno = lineno; 1040 } 1041 sbody 1042 { 1043 $$ = $2->suetag; 1044 if($$->link != T) 1045 diag(Z, "redeclare tag: %s", $2->name); 1046 $$->link = $4; 1047 $$->lineno = saveline; 1048 suallign($$); 1049 } 1050 | LSTRUCT 1051 { 1052 saveline = lineno; 1053 } 1054 sbody 1055 { 1056 char buf[128]; 1057 1058 taggen++; 1059 sprint(symb, "%s_adt_%d", outmod(buf, -1), taggen); 1060 $$ = dotag(lookup(), TSTRUCT, autobn); 1061 $$->link = $3; 1062 $$->lineno = saveline; 1063 lookup()->lineno = saveline; 1064 suallign($$); 1065 } 1066 | LUNION ltag 1067 { 1068 dotag($2, TUNION, 0); 1069 $$ = $2->suetag; 1070 $2->lineno = lineno; 1071 } 1072 | LUNION ltag 1073 { 1074 dotag($2, TUNION, autobn); 1075 saveline = $2->lineno = lineno; 1076 } 1077 sbody 1078 { 1079 $$ = $2->suetag; 1080 if($$->link != T) 1081 diag(Z, "redeclare tag: %s", $2->name); 1082 $$->link = $4; 1083 $$->lineno = saveline; 1084 suallign($$); 1085 } 1086 | LUNION 1087 { 1088 saveline = lineno; 1089 } 1090 sbody 1091 { 1092 char buf[128]; 1093 1094 taggen++; 1095 sprint(symb, "%s_adt_%d", outmod(buf, -1), taggen); 1096 $$ = dotag(lookup(), TUNION, autobn); 1097 $$->link = $3; 1098 $$->lineno = saveline; 1099 lookup()->lineno = saveline; 1100 suallign($$); 1101 } 1102 | LENUM ltag 1103 { 1104 dotag($2, TENUM, 0); 1105 $$ = $2->suetag; 1106 if($$->link == T) 1107 $$->link = types[TINT]; 1108 $$ = $$->link; 1109 $2->lineno = lineno; 1110 } 1111 | LENUM ltag 1112 { 1113 dotag($2, TENUM, autobn); 1114 $2->lineno = lineno; 1115 } 1116 '{' 1117 { 1118 en.tenum = T; 1119 en.cenum = T; 1120 } 1121 enum '}' 1122 { 1123 $$ = $2->suetag; 1124 if($$->link != T) 1125 diag(Z, "redeclare tag: %s", $2->name); 1126 if(en.tenum == T) { 1127 diag(Z, "enum type ambiguous: %s", $2->name); 1128 en.tenum = types[TINT]; 1129 } 1130 $$->link = en.tenum; 1131 $$ = en.tenum; 1132 etgen(nil); 1133 } 1134 | LENUM '{' 1135 { 1136 en.tenum = T; 1137 en.cenum = T; 1138 } 1139 enum '}' 1140 { 1141 $$ = en.tenum; 1142 etgen(nil); 1143 } 1144 | LCTYPE 1145 { 1146 $$ = tcopy($1->type); 1147 } 1148 | LSTYPE 1149 { 1150 $$ = tcopy($1->type); 1151 } 1152 1153 tnlist: 1154 tname 1155 | tnlist tname 1156 { 1157 $$ = typebitor($1, $2); 1158 } 1159 1160 gctnlist: 1161 gctname 1162 | gctnlist gctname 1163 { 1164 $$ = typebitor($1, $2); 1165 } 1166 1167 zgnlist: 1168 { 1169 $$ = 0; 1170 } 1171 | zgnlist gname 1172 { 1173 $$ = typebitor($1, $2); 1174 } 1175 1176 gctname: 1177 tname 1178 | gname 1179 | cname 1180 1181 enum: 1182 LNAME 1183 { 1184 doenum($1, Z); 1185 $1->lineno = lineno; 1186 } 1187 | LNAME '=' expr 1188 { 1189 doenum($1, $3); 1190 $1->lineno = lineno; 1191 } 1192 | enum ',' 1193 | enum ',' enum 1194 1195 tname: /* type words */ 1196 LCHAR { $$ = BCHAR; } 1197 | LSHORT { $$ = BSHORT; } 1198 | LINT { $$ = BINT; } 1199 | LLONG { $$ = BLONG; } 1200 | LSIGNED { $$ = BSIGNED; } 1201 | LUNSIGNED { $$ = BUNSIGNED; } 1202 | LFLOAT { $$ = BFLOAT; } 1203 | LDOUBLE { $$ = BDOUBLE; } 1204 | LVOID { $$ = BVOID; } 1205 | LVLONG { $$ = BVLONG|BLONG; } 1206 1207 cname: /* class words */ 1208 LAUTO { $$ = BAUTO; } 1209 | LSTATIC { $$ = BSTATIC; } 1210 | LEXTERN { $$ = BEXTERN; } 1211 | LTYPEDEF { $$ = BTYPEDEF; } 1212 | LREGISTER { $$ = BREGISTER; } 1213 1214 gname: 1215 LCONSTNT { $$ = BCONSTNT; } 1216 | LVOLATILE { $$ = BVOLATILE; } 1217 1218 name: 1219 LNAME 1220 { 1221 $$ = new(ONAME, Z, Z); 1222 if($1->class == CLOCAL) 1223 $1 = mkstatic($1); 1224 $$->sym = $1; 1225 $$->type = $1->type; 1226 } 1227 tag: 1228 ltag 1229 { 1230 $$ = new(ONAME, Z, Z); 1231 $$->sym = $1; 1232 $$->type = $1->type; 1233 } 1234 ltag: 1235 LNAME 1236 | LCTYPE 1237 | LSTYPE 1238 1239 %% 1240