|
|
1.1 ! root 1: %term NAME 2 ! 2: %term STRING 3 ! 3: %term ICON 4 ! 4: %term FCON 5 ! 5: %term PLUS 6 ! 6: %term MINUS 8 ! 7: %term MUL 11 ! 8: %term AND 14 ! 9: %term OR 17 ! 10: %term ER 19 ! 11: %term QUEST 21 ! 12: %term COLON 22 ! 13: %term ANDAND 23 ! 14: %term OROR 24 ! 15: ! 16: /* special interfaces for yacc alone */ ! 17: /* These serve as abbreviations of 2 or more ops: ! 18: ASOP =, = ops ! 19: RELOP LE,LT,GE,GT ! 20: EQUOP EQ,NE ! 21: DIVOP DIV,MOD ! 22: SHIFTOP LS,RS ! 23: ICOP ICR,DECR ! 24: UNOP NOT,COMPL ! 25: STROP DOT,STREF ! 26: ! 27: */ ! 28: %term ASOP 25 ! 29: %term RELOP 26 ! 30: %term EQUOP 27 ! 31: %term DIVOP 28 ! 32: %term SHIFTOP 29 ! 33: %term INCOP 30 ! 34: %term UNOP 31 ! 35: %term STROP 32 ! 36: ! 37: /* reserved words, etc */ ! 38: %term TYPE 33 ! 39: %term CLASS 34 ! 40: %term STRUCT 35 ! 41: %term RETURN 36 ! 42: %term GOTO 37 ! 43: %term IF 38 ! 44: %term ELSE 39 ! 45: %term SWITCH 40 ! 46: %term BREAK 41 ! 47: %term CONTINUE 42 ! 48: %term WHILE 43 ! 49: %term DO 44 ! 50: %term FOR 45 ! 51: %term DEFAULT 46 ! 52: %term CASE 47 ! 53: %term SIZEOF 48 ! 54: %term ENUM 49 ! 55: ! 56: ! 57: /* little symbols, etc. */ ! 58: /* namely, ! 59: ! 60: LP ( ! 61: RP ) ! 62: ! 63: LC { ! 64: RC } ! 65: ! 66: LB [ ! 67: RB ] ! 68: ! 69: CM , ! 70: SM ; ! 71: ! 72: */ ! 73: ! 74: %term LP 50 ! 75: %term RP 51 ! 76: %term LC 52 ! 77: %term RC 53 ! 78: %term LB 54 ! 79: %term RB 55 ! 80: %term CM 56 ! 81: %term SM 57 ! 82: %term ASSIGN 58 ! 83: ! 84: /* at last count, there were 7 shift/reduce, 1 reduce/reduce conflicts ! 85: /* these involved: ! 86: if/else ! 87: recognizing functions in various contexts, including declarations ! 88: error recovery ! 89: */ ! 90: ! 91: %left CM ! 92: %right ASOP ASSIGN ! 93: %right QUEST COLON ! 94: %left OROR ! 95: %left ANDAND ! 96: %left OR ! 97: %left ER ! 98: %left AND ! 99: %left EQUOP ! 100: %left RELOP ! 101: %left SHIFTOP ! 102: %left PLUS MINUS ! 103: %left MUL DIVOP ! 104: %right UNOP ! 105: %right INCOP SIZEOF ! 106: %left LB LP STROP ! 107: %{ ! 108: # include "mfile1" ! 109: %} ! 110: ! 111: /* define types */ ! 112: %start ext_def_list ! 113: ! 114: %type <intval> con_e ifelprefix ifprefix whprefix forprefix doprefix switchpart ! 115: enum_head str_head name_lp ! 116: %type <nodep> e .e term attributes oattributes type enum_dcl struct_dcl ! 117: cast_type null_decl funct_idn declarator fdeclarator nfdeclarator ! 118: elist ! 119: ! 120: %token <intval> CLASS NAME STRUCT RELOP CM DIVOP PLUS MINUS SHIFTOP MUL AND OR ER ANDAND OROR ! 121: ASSIGN STROP INCOP UNOP ICON ! 122: %token <nodep> TYPE ! 123: ! 124: %% ! 125: ! 126: %{ ! 127: static int fake = 0; ! 128: #ifndef FLEXNAMES ! 129: static char fakename[NCHNAM+1]; ! 130: #else ! 131: static char fakename[24]; ! 132: #endif ! 133: %} ! 134: ! 135: ext_def_list: ext_def_list external_def ! 136: | ! 137: =ftnend(); ! 138: ; ! 139: external_def: data_def ! 140: ={ curclass = SNULL; blevel = 0; } ! 141: | error ! 142: ={ curclass = SNULL; blevel = 0; } ! 143: ; ! 144: data_def: ! 145: oattributes SM ! 146: ={ $1->in.op = FREE; } ! 147: | oattributes init_dcl_list SM ! 148: ={ $1->in.op = FREE; } ! 149: | oattributes fdeclarator { ! 150: defid( tymerge($1,$2), curclass==STATIC?STATIC:EXTDEF ); ! 151: #ifndef LINT ! 152: pfstab(stab[$2->tn.rval].sname); ! 153: #endif ! 154: } function_body ! 155: ={ ! 156: if( blevel ) cerror( "function level error" ); ! 157: if( reached ) retstat |= NRETVAL; ! 158: $1->in.op = FREE; ! 159: ftnend(); ! 160: } ! 161: ; ! 162: ! 163: function_body: arg_dcl_list compoundstmt ! 164: ; ! 165: arg_dcl_list: arg_dcl_list declaration ! 166: | ={ blevel = 1; } ! 167: ; ! 168: ! 169: stmt_list: stmt_list statement ! 170: | /* empty */ ! 171: ={ bccode(); ! 172: locctr(PROG); ! 173: } ! 174: ; ! 175: ! 176: r_dcl_stat_list : dcl_stat_list attributes SM ! 177: ={ $2->in.op = FREE; ! 178: #ifndef LINT ! 179: plcstab(blevel); ! 180: #endif ! 181: } ! 182: | dcl_stat_list attributes init_dcl_list SM ! 183: ={ $2->in.op = FREE; ! 184: #ifndef LINT ! 185: plcstab(blevel); ! 186: #endif ! 187: } ! 188: ; ! 189: ! 190: dcl_stat_list : dcl_stat_list attributes SM ! 191: ={ $2->in.op = FREE; } ! 192: | dcl_stat_list attributes init_dcl_list SM ! 193: ={ $2->in.op = FREE; } ! 194: | /* empty */ ! 195: ; ! 196: declaration: attributes declarator_list SM ! 197: ={ curclass = SNULL; $1->in.op = FREE; } ! 198: | attributes SM ! 199: ={ curclass = SNULL; $1->in.op = FREE; } ! 200: | error SM ! 201: ={ curclass = SNULL; } ! 202: ; ! 203: oattributes: attributes ! 204: | /* VOID */ ! 205: ={ $$ = mkty(INT,0,INT); curclass = SNULL; } ! 206: ; ! 207: attributes: class type ! 208: ={ $$ = $2; } ! 209: | type class ! 210: | class ! 211: ={ $$ = mkty(INT,0,INT); } ! 212: | type ! 213: ={ curclass = SNULL ; } ! 214: | type class type ! 215: ={ $1->in.type = types( $1->in.type, $3->in.type, UNDEF ); ! 216: $3->in.op = FREE; ! 217: } ! 218: ; ! 219: ! 220: ! 221: class: CLASS ! 222: ={ curclass = $1; } ! 223: ; ! 224: ! 225: type: TYPE ! 226: | TYPE TYPE ! 227: ={ $1->in.type = types( $1->in.type, $2->in.type, UNDEF ); ! 228: $2->in.op = FREE; ! 229: } ! 230: | TYPE TYPE TYPE ! 231: ={ $1->in.type = types( $1->in.type, $2->in.type, $3->in.type ); ! 232: $2->in.op = $3->in.op = FREE; ! 233: } ! 234: | struct_dcl ! 235: | enum_dcl ! 236: ; ! 237: ! 238: enum_dcl: enum_head LC moe_list optcomma RC ! 239: ={ $$ = dclstruct($1); } ! 240: | ENUM NAME ! 241: ={ $$ = rstruct($2,0); stwart = instruct; } ! 242: ; ! 243: ! 244: enum_head: ENUM ! 245: ={ $$ = bstruct(-1,0); stwart = SEENAME; } ! 246: | ENUM NAME ! 247: ={ $$ = bstruct($2,0); stwart = SEENAME; } ! 248: ; ! 249: ! 250: moe_list: moe ! 251: | moe_list CM moe ! 252: ; ! 253: ! 254: moe: NAME ! 255: ={ moedef( $1 ); } ! 256: | NAME ASSIGN con_e ! 257: ={ strucoff = $3; moedef( $1 ); } ! 258: ; ! 259: ! 260: struct_dcl: str_head LC type_dcl_list optsemi RC ! 261: ={ $$ = dclstruct($1); } ! 262: | STRUCT NAME ! 263: ={ $$ = rstruct($2,$1); } ! 264: ; ! 265: ! 266: str_head: STRUCT ! 267: ={ $$ = bstruct(-1,$1); stwart=0; } ! 268: | STRUCT NAME ! 269: ={ $$ = bstruct($2,$1); stwart=0; } ! 270: ; ! 271: ! 272: type_dcl_list: type_declaration ! 273: | type_dcl_list SM type_declaration ! 274: ; ! 275: ! 276: type_declaration: type declarator_list ! 277: ={ curclass = SNULL; stwart=0; $1->in.op = FREE; } ! 278: | type ! 279: ={ if( curclass != MOU ){ ! 280: curclass = SNULL; ! 281: } ! 282: else { ! 283: sprintf( fakename, "$%dFAKE", fake++ ); ! 284: #ifdef FLEXSTRINGS ! 285: /* No need to hash this, we won't look it up */ ! 286: defid( tymerge($1, bdty(NAME,NIL,lookup( savestr(fakename), SMOS ))), curclass ); ! 287: #else ! 288: defid( tymerge($1, bdty(NAME,NIL,lookup( fakename, SMOS ))), curclass ); ! 289: #endif ! 290: werror("structure typed union member must be named"); ! 291: } ! 292: stwart = 0; ! 293: $1->in.op = FREE; ! 294: } ! 295: ; ! 296: ! 297: ! 298: declarator_list: declarator ! 299: ={ defid( tymerge($<nodep>0,$1), curclass); stwart = instruct; } ! 300: | declarator_list CM {$<nodep>$=$<nodep>0;} declarator ! 301: ={ defid( tymerge($<nodep>0,$4), curclass); stwart = instruct; } ! 302: ; ! 303: declarator: fdeclarator ! 304: | nfdeclarator ! 305: | nfdeclarator COLON con_e ! 306: %prec CM ! 307: ={ if( !(instruct&INSTRUCT) ) uerror( "field outside of structure" ); ! 308: if( $3<0 || $3 >= FIELD ){ ! 309: uerror( "illegal field size" ); ! 310: $3 = 1; ! 311: } ! 312: defid( tymerge($<nodep>0,$1), FIELD|$3 ); ! 313: $$ = NIL; ! 314: } ! 315: | COLON con_e ! 316: %prec CM ! 317: ={ if( !(instruct&INSTRUCT) ) uerror( "field outside of structure" ); ! 318: falloc( stab, $2, -1, $<nodep>0 ); /* alignment or hole */ ! 319: $$ = NIL; ! 320: } ! 321: | error ! 322: ={ $$ = NIL; } ! 323: ; ! 324: ! 325: /* int (a)(); is not a function --- sorry! */ ! 326: nfdeclarator: MUL nfdeclarator ! 327: ={ umul: ! 328: $$ = bdty( UNARY MUL, $2, 0 ); } ! 329: | nfdeclarator LP RP ! 330: ={ uftn: ! 331: $$ = bdty( UNARY CALL, $1, 0 ); } ! 332: | nfdeclarator LB RB ! 333: ={ uary: ! 334: $$ = bdty( LB, $1, 0 ); } ! 335: | nfdeclarator LB con_e RB ! 336: ={ bary: ! 337: if( (int)$3 <= 0 ) werror( "zero or negative subscript" ); ! 338: $$ = bdty( LB, $1, $3 ); } ! 339: | NAME ! 340: ={ $$ = bdty( NAME, NIL, $1 ); } ! 341: | LP nfdeclarator RP ! 342: ={ $$=$2; } ! 343: ; ! 344: fdeclarator: MUL fdeclarator ! 345: ={ goto umul; } ! 346: | fdeclarator LP RP ! 347: ={ goto uftn; } ! 348: | fdeclarator LB RB ! 349: ={ goto uary; } ! 350: | fdeclarator LB con_e RB ! 351: ={ goto bary; } ! 352: | LP fdeclarator RP ! 353: ={ $$ = $2; } ! 354: | name_lp name_list RP ! 355: ={ ! 356: if( blevel!=0 ) uerror("function declaration in bad context"); ! 357: $$ = bdty( UNARY CALL, bdty(NAME,NIL,$1), 0 ); ! 358: stwart = 0; ! 359: } ! 360: | name_lp RP ! 361: ={ ! 362: $$ = bdty( UNARY CALL, bdty(NAME,NIL,$1), 0 ); ! 363: stwart = 0; ! 364: } ! 365: ; ! 366: ! 367: name_lp: NAME LP ! 368: ={ ! 369: /* turn off typedefs for argument names */ ! 370: stwart = SEENAME; ! 371: if( stab[$1].sclass == SNULL ) ! 372: stab[$1].stype = FTN; ! 373: } ! 374: ; ! 375: ! 376: name_list: NAME ! 377: ={ ftnarg( $1 ); stwart = SEENAME; } ! 378: | name_list CM NAME ! 379: ={ ftnarg( $3 ); stwart = SEENAME; } ! 380: | error ! 381: ; ! 382: /* always preceeded by attributes: thus the $<nodep>0's */ ! 383: init_dcl_list: init_declarator ! 384: %prec CM ! 385: | init_dcl_list CM {$<nodep>$=$<nodep>0;} init_declarator ! 386: ; ! 387: /* always preceeded by attributes */ ! 388: xnfdeclarator: nfdeclarator ! 389: ={ defid( $1 = tymerge($<nodep>0,$1), curclass); ! 390: beginit($1->tn.rval); ! 391: } ! 392: | error ! 393: ; ! 394: /* always preceeded by attributes */ ! 395: init_declarator: nfdeclarator ! 396: ={ nidcl( tymerge($<nodep>0,$1) ); } ! 397: | fdeclarator ! 398: ={ defid( tymerge($<nodep>0,$1), uclass(curclass) ); ! 399: } ! 400: | xnfdeclarator optasgn e ! 401: %prec CM ! 402: ={ doinit( $3 ); ! 403: endinit(); } ! 404: | xnfdeclarator optasgn LC init_list optcomma RC ! 405: ={ endinit(); } ! 406: | error ! 407: ; ! 408: ! 409: init_list: initializer ! 410: %prec CM ! 411: | init_list CM initializer ! 412: ; ! 413: initializer: e ! 414: %prec CM ! 415: ={ doinit( $1 ); } ! 416: | ibrace init_list optcomma RC ! 417: ={ irbrace(); } ! 418: ; ! 419: ! 420: optcomma : /* VOID */ ! 421: | CM ! 422: ; ! 423: ! 424: optsemi : /* VOID */ ! 425: | SM ! 426: ; ! 427: ! 428: optasgn : /* VOID */ ! 429: ={ werror( "old-fashioned initialization: use =" ); } ! 430: | ASSIGN ! 431: ; ! 432: ! 433: ibrace : LC ! 434: ={ ilbrace(); } ! 435: ; ! 436: ! 437: /* STATEMENTS */ ! 438: ! 439: compoundstmt: dcmpstmt ! 440: | cmpstmt ! 441: ; ! 442: ! 443: dcmpstmt: begin r_dcl_stat_list stmt_list RC ! 444: ={ ! 445: #ifndef LINT ! 446: prcstab(blevel); ! 447: #endif ! 448: --blevel; ! 449: if( blevel == 1 ) blevel = 0; ! 450: clearst( blevel ); ! 451: checkst( blevel ); ! 452: autooff = *--psavbc; ! 453: regvar = *--psavbc; ! 454: } ! 455: ; ! 456: ! 457: cmpstmt: begin stmt_list RC ! 458: ={ --blevel; ! 459: if( blevel == 1 ) blevel = 0; ! 460: clearst( blevel ); ! 461: checkst( blevel ); ! 462: autooff = *--psavbc; ! 463: regvar = *--psavbc; ! 464: } ! 465: ; ! 466: ! 467: begin: LC ! 468: ={ if( blevel == 1 ) dclargs(); ! 469: ++blevel; ! 470: if( psavbc > &asavbc[BCSZ-2] ) cerror( "nesting too deep" ); ! 471: *psavbc++ = regvar; ! 472: *psavbc++ = autooff; ! 473: } ! 474: ; ! 475: ! 476: statement: e SM ! 477: ={ ecomp( $1 ); } ! 478: | compoundstmt ! 479: | ifprefix statement ! 480: ={ deflab($1); ! 481: reached = 1; ! 482: } ! 483: | ifelprefix statement ! 484: ={ if( $1 != NOLAB ){ ! 485: deflab( $1 ); ! 486: reached = 1; ! 487: } ! 488: } ! 489: | whprefix statement ! 490: ={ branch( contlab ); ! 491: deflab( brklab ); ! 492: if( (flostat&FBRK) || !(flostat&FLOOP)) reached = 1; ! 493: else reached = 0; ! 494: resetbc(0); ! 495: } ! 496: | doprefix statement WHILE LP e RP SM ! 497: ={ deflab( contlab ); ! 498: if( flostat & FCONT ) reached = 1; ! 499: ecomp( buildtree( CBRANCH, buildtree( NOT, $5, NIL ), bcon( $1 ) ) ); ! 500: deflab( brklab ); ! 501: reached = 1; ! 502: resetbc(0); ! 503: } ! 504: | forprefix .e RP statement ! 505: ={ deflab( contlab ); ! 506: if( flostat&FCONT ) reached = 1; ! 507: if( $2 ) ecomp( $2 ); ! 508: branch( $1 ); ! 509: deflab( brklab ); ! 510: if( (flostat&FBRK) || !(flostat&FLOOP) ) reached = 1; ! 511: else reached = 0; ! 512: resetbc(0); ! 513: } ! 514: | switchpart statement ! 515: ={ if( reached ) branch( brklab ); ! 516: deflab( $1 ); ! 517: swend(); ! 518: deflab(brklab); ! 519: if( (flostat&FBRK) || !(flostat&FDEF) ) reached = 1; ! 520: resetbc(FCONT); ! 521: } ! 522: | BREAK SM ! 523: ={ if( brklab == NOLAB ) uerror( "illegal break"); ! 524: else if(reached) branch( brklab ); ! 525: flostat |= FBRK; ! 526: if( brkflag ) goto rch; ! 527: reached = 0; ! 528: } ! 529: | CONTINUE SM ! 530: ={ if( contlab == NOLAB ) uerror( "illegal continue"); ! 531: else branch( contlab ); ! 532: flostat |= FCONT; ! 533: goto rch; ! 534: } ! 535: | RETURN SM ! 536: ={ retstat |= NRETVAL; ! 537: branch( retlab ); ! 538: rch: ! 539: if( !reached ) werror( "statement not reached"); ! 540: reached = 0; ! 541: } ! 542: | RETURN e SM ! 543: ={ register NODE *temp; ! 544: idname = curftn; ! 545: temp = buildtree( NAME, NIL, NIL ); ! 546: if(temp->in.type == TVOID) ! 547: uerror("void function %s cannot return value", ! 548: stab[idname].sname); ! 549: temp->in.type = DECREF( temp->in.type ); ! 550: temp = buildtree( RETURN, temp, $2 ); ! 551: /* now, we have the type of the RHS correct */ ! 552: temp->in.left->in.op = FREE; ! 553: temp->in.op = FREE; ! 554: ecomp( buildtree( FORCE, temp->in.right, NIL ) ); ! 555: retstat |= RETVAL; ! 556: branch( retlab ); ! 557: reached = 0; ! 558: } ! 559: | GOTO NAME SM ! 560: ={ register NODE *q; ! 561: q = block( FREE, NIL, NIL, INT|ARY, 0, INT ); ! 562: q->tn.rval = idname = $2; ! 563: defid( q, ULABEL ); ! 564: stab[idname].suse = -lineno; ! 565: branch( stab[idname].offset ); ! 566: goto rch; ! 567: } ! 568: | SM ! 569: | error SM ! 570: | error RC ! 571: | label statement ! 572: ; ! 573: label: NAME COLON ! 574: ={ register NODE *q; ! 575: q = block( FREE, NIL, NIL, INT|ARY, 0, LABEL ); ! 576: q->tn.rval = $1; ! 577: defid( q, LABEL ); ! 578: reached = 1; ! 579: } ! 580: | CASE e COLON ! 581: ={ addcase($2); ! 582: reached = 1; ! 583: } ! 584: | DEFAULT COLON ! 585: ={ reached = 1; ! 586: adddef(); ! 587: flostat |= FDEF; ! 588: } ! 589: ; ! 590: doprefix: DO ! 591: ={ savebc(); ! 592: if( !reached ) werror( "loop not entered at top"); ! 593: brklab = getlab(); ! 594: contlab = getlab(); ! 595: deflab( $$ = getlab() ); ! 596: reached = 1; ! 597: } ! 598: ; ! 599: ifprefix: IF LP e RP ! 600: ={ ecomp( buildtree( CBRANCH, $3, bcon( $$=getlab()) ) ) ; ! 601: reached = 1; ! 602: } ! 603: ; ! 604: ifelprefix: ifprefix statement ELSE ! 605: ={ if( reached ) branch( $$ = getlab() ); ! 606: else $$ = NOLAB; ! 607: deflab( $1 ); ! 608: reached = 1; ! 609: } ! 610: ; ! 611: ! 612: whprefix: WHILE LP e RP ! 613: ={ savebc(); ! 614: if( !reached ) werror( "loop not entered at top"); ! 615: if( $3->in.op == ICON && $3->tn.lval != 0 ) flostat = FLOOP; ! 616: deflab( contlab = getlab() ); ! 617: reached = 1; ! 618: brklab = getlab(); ! 619: if( flostat == FLOOP ) tfree( $3 ); ! 620: else ecomp( buildtree( CBRANCH, $3, bcon( brklab) ) ); ! 621: } ! 622: ; ! 623: forprefix: FOR LP .e SM .e SM ! 624: ={ if( $3 ) ecomp( $3 ); ! 625: else if( !reached ) werror( "loop not entered at top"); ! 626: savebc(); ! 627: contlab = getlab(); ! 628: brklab = getlab(); ! 629: deflab( $$ = getlab() ); ! 630: reached = 1; ! 631: if( $5 ) ecomp( buildtree( CBRANCH, $5, bcon( brklab) ) ); ! 632: else flostat |= FLOOP; ! 633: } ! 634: ; ! 635: switchpart: SWITCH LP e RP ! 636: ={ savebc(); ! 637: brklab = getlab(); ! 638: ecomp( buildtree( FORCE, $3, NIL ) ); ! 639: branch( $$ = getlab() ); ! 640: swstart(); ! 641: reached = 0; ! 642: } ! 643: ; ! 644: /* EXPRESSIONS */ ! 645: con_e: { $<intval>$=instruct; stwart=instruct=0; } e ! 646: %prec CM ! 647: ={ $$ = icons( $2 ); instruct=$<intval>1; } ! 648: ; ! 649: .e: e ! 650: | ! 651: ={ $$=0; } ! 652: ; ! 653: elist: e ! 654: %prec CM ! 655: | elist CM e ! 656: ={ goto bop; } ! 657: ; ! 658: ! 659: e: e RELOP e ! 660: ={ ! 661: preconf: ! 662: if( yychar==RELOP||yychar==EQUOP||yychar==AND||yychar==OR||yychar==ER ){ ! 663: precplaint: ! 664: if( hflag ) werror( "precedence confusion possible: parenthesize!" ); ! 665: } ! 666: bop: ! 667: $$ = buildtree( $2, $1, $3 ); ! 668: } ! 669: | e CM e ! 670: ={ $2 = COMOP; ! 671: goto bop; ! 672: } ! 673: | e DIVOP e ! 674: ={ goto bop; } ! 675: | e PLUS e ! 676: ={ if(yychar==SHIFTOP) goto precplaint; else goto bop; } ! 677: | e MINUS e ! 678: ={ if(yychar==SHIFTOP ) goto precplaint; else goto bop; } ! 679: | e SHIFTOP e ! 680: ={ if(yychar==PLUS||yychar==MINUS) goto precplaint; else goto bop; } ! 681: | e MUL e ! 682: ={ goto bop; } ! 683: | e EQUOP e ! 684: ={ goto preconf; } ! 685: | e AND e ! 686: ={ if( yychar==RELOP||yychar==EQUOP ) goto preconf; else goto bop; } ! 687: | e OR e ! 688: ={ if(yychar==RELOP||yychar==EQUOP) goto preconf; else goto bop; } ! 689: | e ER e ! 690: ={ if(yychar==RELOP||yychar==EQUOP) goto preconf; else goto bop; } ! 691: | e ANDAND e ! 692: ={ goto bop; } ! 693: | e OROR e ! 694: ={ goto bop; } ! 695: | e MUL ASSIGN e ! 696: ={ abop: ! 697: $$ = buildtree( ASG $2, $1, $4 ); ! 698: } ! 699: | e DIVOP ASSIGN e ! 700: ={ goto abop; } ! 701: | e PLUS ASSIGN e ! 702: ={ goto abop; } ! 703: | e MINUS ASSIGN e ! 704: ={ goto abop; } ! 705: | e SHIFTOP ASSIGN e ! 706: ={ goto abop; } ! 707: | e AND ASSIGN e ! 708: ={ goto abop; } ! 709: | e OR ASSIGN e ! 710: ={ goto abop; } ! 711: | e ER ASSIGN e ! 712: ={ goto abop; } ! 713: | e QUEST e COLON e ! 714: ={ $$=buildtree(QUEST, $1, buildtree( COLON, $3, $5 ) ); ! 715: } ! 716: | e ASOP e ! 717: ={ werror( "old-fashioned assignment operator" ); goto bop; } ! 718: | e ASSIGN e ! 719: ={ goto bop; } ! 720: | term ! 721: ; ! 722: term: term INCOP ! 723: ={ $$ = buildtree( $2, $1, bcon(1) ); } ! 724: | MUL term ! 725: ={ ubop: ! 726: $$ = buildtree( UNARY $1, $2, NIL ); ! 727: } ! 728: | AND term ! 729: ={ if( ISFTN($2->in.type) || ISARY($2->in.type) ){ ! 730: werror( "& before array or function: ignored" ); ! 731: $$ = $2; ! 732: } ! 733: else goto ubop; ! 734: } ! 735: | MINUS term ! 736: ={ goto ubop; } ! 737: | UNOP term ! 738: ={ ! 739: $$ = buildtree( $1, $2, NIL ); ! 740: } ! 741: | INCOP term ! 742: ={ $$ = buildtree( $1==INCR ? ASG PLUS : ASG MINUS, ! 743: $2, ! 744: bcon(1) ); ! 745: } ! 746: | SIZEOF term ! 747: ={ $$ = doszof( $2 ); } ! 748: | LP cast_type RP term %prec INCOP ! 749: ={ $$ = buildtree( CAST, $2, $4 ); ! 750: $$->in.left->in.op = FREE; ! 751: $$->in.op = FREE; ! 752: $$ = $$->in.right; ! 753: } ! 754: | SIZEOF LP cast_type RP %prec SIZEOF ! 755: ={ $$ = doszof( $3 ); } ! 756: | term LB e RB ! 757: ={ $$ = buildtree( UNARY MUL, buildtree( PLUS, $1, $3 ), NIL ); } ! 758: | funct_idn RP ! 759: ={ $$=buildtree(UNARY CALL,$1,NIL); } ! 760: | funct_idn elist RP ! 761: ={ $$=buildtree(CALL,$1,$2); } ! 762: | term STROP NAME ! 763: ={ if( $2 == DOT ){ ! 764: if( notlval( $1 ) )uerror("structure reference must be addressable"); ! 765: $1 = buildtree( UNARY AND, $1, NIL ); ! 766: } ! 767: idname = $3; ! 768: $$ = buildtree( STREF, $1, buildtree( NAME, NIL, NIL ) ); ! 769: } ! 770: | NAME ! 771: ={ idname = $1; ! 772: /* recognize identifiers in initializations */ ! 773: if( blevel==0 && stab[idname].stype == UNDEF ) { ! 774: register NODE *q; ! 775: #ifndef FLEXNAMES ! 776: werror( "undeclared initializer name %.8s", stab[idname].sname ); ! 777: #else ! 778: werror( "undeclared initializer name %s", stab[idname].sname ); ! 779: #endif ! 780: q = block( FREE, NIL, NIL, INT, 0, INT ); ! 781: q->tn.rval = idname; ! 782: defid( q, EXTERN ); ! 783: } ! 784: $$=buildtree(NAME,NIL,NIL); ! 785: stab[$1].suse = -lineno; ! 786: } ! 787: | ICON ! 788: ={ $$=bcon(0); ! 789: $$->tn.lval = lastcon; ! 790: $$->tn.rval = NONAME; ! 791: if( $1 ) $$->fn.csiz = $$->in.type = ctype(LONG); ! 792: } ! 793: | FCON ! 794: ={ $$=buildtree(FCON,NIL,NIL); ! 795: $$->fpn.dval = dcon; ! 796: } ! 797: | STRING ! 798: ={ $$ = getstr(); /* get string contents */ } ! 799: | LP e RP ! 800: ={ $$=$2; } ! 801: ; ! 802: ! 803: cast_type: type null_decl ! 804: ={ ! 805: $$ = tymerge( $1, $2 ); ! 806: $$->in.op = NAME; ! 807: $1->in.op = FREE; ! 808: } ! 809: ; ! 810: ! 811: null_decl: /* empty */ ! 812: ={ $$ = bdty( NAME, NIL, -1 ); } ! 813: | LP RP ! 814: ={ $$ = bdty( UNARY CALL, bdty(NAME,NIL,-1),0); } ! 815: | LP null_decl RP LP RP ! 816: ={ $$ = bdty( UNARY CALL, $2, 0 ); } ! 817: | MUL null_decl ! 818: ={ goto umul; } ! 819: | null_decl LB RB ! 820: ={ goto uary; } ! 821: | null_decl LB con_e RB ! 822: ={ goto bary; } ! 823: | LP null_decl RP ! 824: ={ $$ = $2; } ! 825: ; ! 826: ! 827: funct_idn: NAME LP ! 828: ={ if( stab[$1].stype == UNDEF ){ ! 829: register NODE *q; ! 830: q = block( FREE, NIL, NIL, FTN|INT, 0, INT ); ! 831: q->tn.rval = $1; ! 832: defid( q, EXTERN ); ! 833: } ! 834: idname = $1; ! 835: $$=buildtree(NAME,NIL,NIL); ! 836: stab[idname].suse = -lineno; ! 837: } ! 838: | term LP ! 839: ; ! 840: %% ! 841: ! 842: NODE * ! 843: mkty( t, d, s ) unsigned t; { ! 844: return( block( TYPE, NIL, NIL, t, d, s ) ); ! 845: } ! 846: ! 847: NODE * ! 848: bdty( op, p, v ) NODE *p; { ! 849: register NODE *q; ! 850: ! 851: q = block( op, p, NIL, INT, 0, INT ); ! 852: ! 853: switch( op ){ ! 854: ! 855: case UNARY MUL: ! 856: case UNARY CALL: ! 857: break; ! 858: ! 859: case LB: ! 860: q->in.right = bcon(v); ! 861: break; ! 862: ! 863: case NAME: ! 864: q->tn.rval = v; ! 865: break; ! 866: ! 867: default: ! 868: cerror( "bad bdty" ); ! 869: } ! 870: ! 871: return( q ); ! 872: } ! 873: ! 874: dstash( n ){ /* put n into the dimension table */ ! 875: if( curdim >= DIMTABSZ-1 ){ ! 876: cerror( "dimension table overflow"); ! 877: } ! 878: dimtab[ curdim++ ] = n; ! 879: } ! 880: ! 881: savebc() { ! 882: if( psavbc > & asavbc[BCSZ-4 ] ){ ! 883: cerror( "whiles, fors, etc. too deeply nested"); ! 884: } ! 885: *psavbc++ = brklab; ! 886: *psavbc++ = contlab; ! 887: *psavbc++ = flostat; ! 888: *psavbc++ = swx; ! 889: flostat = 0; ! 890: } ! 891: ! 892: resetbc(mask){ ! 893: ! 894: swx = *--psavbc; ! 895: flostat = *--psavbc | (flostat&mask); ! 896: contlab = *--psavbc; ! 897: brklab = *--psavbc; ! 898: ! 899: } ! 900: ! 901: addcase(p) NODE *p; { /* add case to switch */ ! 902: ! 903: p = optim( p ); /* change enum to ints */ ! 904: if( p->in.op != ICON ){ ! 905: uerror( "non-constant case expression"); ! 906: return; ! 907: } ! 908: if( swp == swtab ){ ! 909: uerror( "case not in switch"); ! 910: return; ! 911: } ! 912: if( swp >= &swtab[SWITSZ] ){ ! 913: cerror( "switch table overflow"); ! 914: } ! 915: swp->sval = p->tn.lval; ! 916: deflab( swp->slab = getlab() ); ! 917: ++swp; ! 918: tfree(p); ! 919: } ! 920: ! 921: adddef(){ /* add default case to switch */ ! 922: if( swtab[swx].slab >= 0 ){ ! 923: uerror( "duplicate default in switch"); ! 924: return; ! 925: } ! 926: if( swp == swtab ){ ! 927: uerror( "default not inside switch"); ! 928: return; ! 929: } ! 930: deflab( swtab[swx].slab = getlab() ); ! 931: } ! 932: ! 933: swstart(){ ! 934: /* begin a switch block */ ! 935: if( swp >= &swtab[SWITSZ] ){ ! 936: cerror( "switch table overflow"); ! 937: } ! 938: swx = swp - swtab; ! 939: swp->slab = -1; ! 940: ++swp; ! 941: } ! 942: ! 943: swend(){ /* end a switch block */ ! 944: ! 945: register struct sw *swbeg, *p, *q, *r, *r1; ! 946: CONSZ temp; ! 947: int tempi; ! 948: ! 949: swbeg = &swtab[swx+1]; ! 950: ! 951: /* sort */ ! 952: ! 953: r1 = swbeg; ! 954: r = swp-1; ! 955: ! 956: while( swbeg < r ){ ! 957: /* bubble largest to end */ ! 958: for( q=swbeg; q<r; ++q ){ ! 959: if( q->sval > (q+1)->sval ){ ! 960: /* swap */ ! 961: r1 = q+1; ! 962: temp = q->sval; ! 963: q->sval = r1->sval; ! 964: r1->sval = temp; ! 965: tempi = q->slab; ! 966: q->slab = r1->slab; ! 967: r1->slab = tempi; ! 968: } ! 969: } ! 970: r = r1; ! 971: r1 = swbeg; ! 972: } ! 973: ! 974: /* it is now sorted */ ! 975: ! 976: for( p = swbeg+1; p<swp; ++p ){ ! 977: if( p->sval == (p-1)->sval ){ ! 978: uerror( "duplicate case in switch, %d", tempi=p->sval ); ! 979: return; ! 980: } ! 981: } ! 982: ! 983: genswitch( swbeg-1, swp-swbeg ); ! 984: swp = swbeg-1; ! 985: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.