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