|
|
1.1 ! root 1: %{ ! 2: static char ID[] = "@(#) ld.yac: 1.8 12/1/83"; ! 3: #include "system.h" ! 4: #include <stdio.h> ! 5: #include "bool.h" ! 6: #include "attributes.h" ! 7: #include "list.h" ! 8: #include "structs.h" ! 9: ! 10: #if TRVEC ! 11: #include "tv.h" ! 12: #include "ldtv.h" ! 13: #endif ! 14: ! 15: #include "extrns.h" ! 16: #include "sgs.h" ! 17: #include "sgsmacros.h" ! 18: #include "ldmacros.h" ! 19: ! 20: ! 21: ! 22: extern char inline[]; ! 23: ! 24: ! 25: /* ! 26: * ! 27: * There is a very important variable, called ! 28: * ! 29: * in_y_exp ! 30: * ! 31: * that is used to help recognize filenames. ! 32: * ! 33: * The problems is this: a UNIX filename can contain ! 34: * virtually any character, and the nodes in the pathname ! 35: * are separated by slashes. Unfortunately, slashes also ! 36: * occur in expressions, comments, and the /= assignment ! 37: * operator. Moreover, the LEX rules ignore white space, ! 38: * which is important to knowing where one filename stops ! 39: * and the next begins. ! 40: * ! 41: * The resolution is this. Lex doesn't know enough alone to ! 42: * recognize a filename; so we give it some help. Whenever we ! 43: * are in an expression, we set in_y_exp to TRUE, and then lex knows ! 44: * that any slash is a slash, and should not be kept as part of ! 45: * a filename. a/b is a divided by b, not the file a/b. ! 46: * ! 47: * Consequently, whenever a slash must be kept as a slash, ! 48: * in_y_exp will be TRUE. Otherwise, it will be FALSE, and the ! 49: * lexical analyzer will treat a/b as a filename. ! 50: */ ! 51: ! 52: int in_y_exp; ! 53: ! 54: static secnum; /* number of sections */ ! 55: static char *fnamptr; ! 56: static int nsecspcs, fillflag; /* parsing status flags */ ! 57: static ACTITEM *aiptr, *afaiptr, *grptr; /* pointers to action items */ ! 58: extern char *curfilnm; /* name of current ifile */ ! 59: ! 60: #if TRVEC ! 61: static TVASSIGN *tvslotn, /* ptr to last in list of tv slots */ ! 62: *slotptr; /* temp for traversing list */ ! 63: #endif ! 64: ! 65: static int tempi; /* temporary int */ ! 66: /*eject*/ ! 67: %} ! 68: /*eject*/ ! 69: %token <sptr> NAME 2 /* ld directives and their component tokens */ ! 70: %token <lptr> LONGINT 3 ! 71: %token <ivalue> INT 4 ! 72: %token <ivalue> ALIGN 5 ! 73: %token <ivalue> DOT 6 ! 74: %token <ivalue> LEN 7 ! 75: %token <ivalue> MEMORY 8 ! 76: %token <ivalue> ORG 9 ! 77: %token <ivalue> REGIONS 10 ! 78: %token <ivalue> SECTIONS 11 ! 79: %token <ivalue> PHY 12 ! 80: ! 81: %token <ivalue> AND 13 /* operators */ ! 82: %token <ivalue> ANDAND 14 ! 83: %token <ivalue> BNOT 15 /* bitwise NOT "~" */ ! 84: %token <ivalue> COLON 16 ! 85: %token <ivalue> COMMA 17 ! 86: %token <ivalue> DIV 18 ! 87: %token <ivalue> EQ 19 ! 88: %token <ivalue> EQEQ 20 ! 89: %token <ivalue> GE 21 ! 90: %token <ivalue> GT 23 ! 91: %token <ivalue> LBRACE 24 ! 92: %token <ivalue> LE 26 ! 93: %token <ivalue> LPAREN 27 ! 94: %token <ivalue> LSHIFT 28 ! 95: %token <ivalue> LT 29 ! 96: %token <ivalue> MINUS 30 ! 97: %token <ivalue> MULT 31 ! 98: %token <ivalue> NE 32 ! 99: %token <ivalue> NOT 33 ! 100: %token <ivalue> OR 34 ! 101: %token <ivalue> OROR 35 ! 102: %token <ivalue> PC 36 ! 103: %token <ivalue> PLUS 37 ! 104: %token <ivalue> RBRACE 38 ! 105: %token <ivalue> RPAREN 39 ! 106: %token <ivalue> RSHIFT 40 ! 107: %token <ivalue> SEMICOL 41 ! 108: /* operator assignments */ ! 109: %token <ivalue> DIVEQ 42 ! 110: %token <ivalue> MINUSEQ 43 ! 111: %token <ivalue> MULTEQ 44 ! 112: %token <ivalue> PLUSEQ 45 ! 113: ! 114: %token <sptr> FILENAME 46 ! 115: %token <ivalue> TV 47 ! 116: %token <ivalue> SPARE 48 ! 117: ! 118: %token <ivalue> DSECT 49 ! 119: %token <ivalue> NOLOAD 50 ! 120: %token <ivalue> COPY 51 ! 121: %token <ivalue> INFO 52 ! 122: ! 123: %token <ivalue> BLOCK 53 ! 124: ! 125: %token <ivalue> UMINUS 54 ! 126: %token <ivalue> GROUP 55 ! 127: %token <ivalue> RANGE 56 ! 128: %token <ivalue> ASSIGN 57 ! 129: ! 130: ! 131: ! 132: ! 133: %type <enode> assnment /* link value types with nonterminals */ ! 134: %type <ivalue> assnop ! 135: %type <ivalue> attr ! 136: %type <enode> ename ! 137: %type <enode> expr ! 138: %type <sptr> filename ! 139: %type <ivalue> fillspc ! 140: %type <aitem> flgstmt2 ! 141: %type <ivalue> inclspc ! 142: %type <ivalue> opt_attr ! 143: %type <lptr> opt_block ! 144: %type <lptr> opt_org ! 145: %type <lptr> opt_aln ! 146: %type <ivalue> opt_type ! 147: %type <enode> term ! 148: %type <lptr> vaddr ! 149: ! 150: ! 151: ! 152: ! 153: %right EQ PLUSEQ MINUSEQ MULTEQ DIVEQ ! 154: %left OROR ! 155: %left ANDAND ! 156: %left OR ! 157: %left AND ! 158: %binary EQEQ NE GT LT LE GE ! 159: %left LSHIFT RSHIFT ! 160: %left PLUS MINUS ! 161: %left MULT DIV PC ! 162: %right NOT BNOT ! 163: %left LPAREN ! 164: ! 165: ! 166: ! 167: %union { ! 168: int ivalue; /* yylval values */ ! 169: char *sptr; ! 170: long *lptr; ! 171: ! 172: ACTITEM *aitem; /* nonterminal values */ ! 173: ENODE *enode; ! 174: } ! 175: /*eject*/ ! 176: %% ! 177: ! 178: wholefile: cmds = ; ! 179: ! 180: cmds: cmds cmd ! 181: | /* empty */ ! 182: = ; ! 183: ! 184: cmd: regspecs ! 185: | memspecs ! 186: | tvspecs ! 187: | secspecs ! 188: | assnment = { ! 189: bldexp($1, &explist); ! 190: } ! 191: | filename = { ! 192: filespec($1); ! 193: } ! 194: | flagstmt ! 195: | error = { ! 196: for( tempi = lineno; tempi == lineno; ) ! 197: yychar = yylex(); ! 198: yyerrok; ! 199: yyclearin; ! 200: } ! 201: ; ! 202: /*eject*/ ! 203: regspecs: REGIONS LBRACE reglist RBRACE = { ! 204: #if USEREGIONS == 0 ! 205: yyerror("REGIONS command not allowed in a %s load", SGS); ! 206: #endif ! 207: } ! 208: ; ! 209: ! 210: reglist: rgnspc ! 211: | reglist rgnspc = ; ! 212: ! 213: rgnspc: NAME COLON ORG EQ LONGINT com LEN EQ LONGINT com vaddr = { ! 214: long *orgp, *lenp, *vaddrp, vzero; ! 215: REGION *rgnp; ! 216: orgp = $5; ! 217: lenp = $9; ! 218: if (*lenp <= 0) ! 219: yyerror("region %s has invalid length",$1); ! 220: if ( (vaddrp = $11) == NULL ) ! 221: vzero = *orgp; ! 222: else ! 223: vzero = *orgp - *vaddrp; ! 224: if ( (vzero & 0xfL) != 0 ) { ! 225: yyerror("virtual 0 (paddr %.1lx) of region %s is not a multiple of 16", ! 226: vzero, $1); ! 227: vzero &= ~0xfL; ! 228: } ! 229: rgnp = (REGION *) myalloc(sizeof(REGION)); ! 230: rgnp->rgorig = *orgp; ! 231: rgnp->rglength = *lenp; ! 232: rgnp->rgvaddr = (vaddrp == NULL) ? 0L : *vaddrp; ! 233: if( (rgnp->rgvaddr + rgnp->rglength) > 0x10000L ) { ! 234: yyerror("addresses of region %s (vaddr=%.1lx len=%.1lx) exceed 64K", ! 235: $1, rgnp->rgvaddr, *lenp); ! 236: rgnp->rglength = 0x10000L - rgnp->rgvaddr; ! 237: } ! 238: strncpy( rgnp->rgname, $1, 8 ); ! 239: listadd(l_REG, ®list, rgnp); ! 240: } ! 241: | error = { ! 242: yyerror("REGIONS specification ignored"); ! 243: } ! 244: ; ! 245: ! 246: com: COMMA ! 247: | /* empty */ ! 248: = ; ! 249: ! 250: vaddr: DOT EQ LONGINT = { ! 251: if ( *(long *) $3 > 0xffffL ) { ! 252: yyerror("virtual address %.1lx exceeds 0xffff: truncated to %.1lx", ! 253: *(long *) $3, *(long *) $3 & 0xffffL); ! 254: *(long *) $3 &= 0xffffL; ! 255: } ! 256: $$ = $3; ! 257: } ! 258: | /* empty */ ! 259: = { ! 260: $$ = NULL; ! 261: } ! 262: ; ! 263: /*eject*/ ! 264: memspecs: MEMORY LBRACE memlist RBRACE = ! 265: ; ! 266: ! 267: memlist: memspc ! 268: | memlist memspc = ; ! 269: ! 270: memspc: NAME opt_attr COLON ORG EQ LONGINT com LEN EQ LONGINT com = { ! 271: long *orgp, *lenp; ! 272: MEMTYPE *memp; ! 273: orgp = $6; ! 274: lenp = $10; ! 275: memp = (MEMTYPE *) myalloc(sizeof(MEMTYPE)); ! 276: memp->mtorig = *orgp; ! 277: memp->mtlength = *lenp; ! 278: memp->mtattr = $2; ! 279: strncpy( memp->mtname, $1, 8 ); ! 280: listadd(l_MEM, &memlist, memp); ! 281: } ! 282: | error = { ! 283: yyerror("MEMORY specification ignored"); ! 284: } ! 285: ; ! 286: ! 287: opt_attr: attr = { ! 288: $$ = $1; ! 289: } ! 290: | = { /* empty */ ! 291: $$ = att_R | att_W | att_X | att_I; ! 292: } ! 293: ; ! 294: ! 295: attr: LPAREN NAME RPAREN = { ! 296: int attflgs; ! 297: char *p; ! 298: attflgs = 0; ! 299: for( p = $2; *p; p++ ) ! 300: switch (*p) { ! 301: case 'R': attflgs |= att_R; break; ! 302: case 'W': attflgs |= att_W; break; ! 303: case 'X': attflgs |= att_X; break; ! 304: case 'I': attflgs |= att_I; break; ! 305: default: yyerror("bad attribute value in MEMORY directive: %c", *p); ! 306: } ! 307: $$ = attflgs; ! 308: } ! 309: ; ! 310: /*eject*/ ! 311: tvspecs: TV opt_long LBRACE tvlist RBRACE tvfill = { ! 312: #if TRVEC ! 313: int length; ! 314: ! 315: tvspec.tvinflnm = curfilnm; ! 316: tvspec.tvinlnno = lineno; ! 317: ! 318: length = 0; ! 319: for( slotptr = tvslot1; slotptr != NULL; slotptr = slotptr->nxtslot ) { ! 320: TVASSIGN *slotptr2; ! 321: length = max(length, slotptr->slot); ! 322: for (slotptr2 = tvslot1; slotptr2 != slotptr; slotptr2 = slotptr2->nxtslot ) ! 323: if (slotptr2->slot == slotptr->slot) { ! 324: lderror(1,0,NULL, ! 325: "function %s assigned to tv slot %d which is already in use", slotptr->funname, slotptr->slot); ! 326: break; ! 327: } ! 328: } ! 329: if( tvspec.tvlength > 0 ) { ! 330: if( length > tvspec.tvlength ) { ! 331: yyerror("ASSIGN slot %d exceeds total TV size of %d", ! 332: length, tvspec.tvlength); ! 333: tvspec.tvlength = length; ! 334: } ! 335: if( tvspec.tvrange[1] > tvspec.tvlength ) { ! 336: yyerror("RANGE value %d exceeds total TV size of %d", ! 337: tvspec.tvrange[1], tvspec.tvlength); ! 338: tvspec.tvlength = tvspec.tvrange[1]; ! 339: } ! 340: } ! 341: else ! 342: tvspec.tvlength = max(length, tvspec.tvrange[1]); ! 343: #else ! 344: yyerror("usage of unimplemented syntax"); ! 345: #endif ! 346: } ! 347: ; ! 348: ! 349: tvlist: SPARE EQ LONGINT = { ! 350: #if TRVEC ! 351: tvspec.tvosptr = (OUTSECT *) ((unsigned) *(long *) $3); ! 352: #else ! 353: yyerror("usage of unimplemented syntax"); ! 354: #endif ! 355: } ! 356: | tvdirlist ! 357: ; ! 358: ! 359: tvdirlist: tvdir tvdirlist ! 360: | /* empty */ ! 361: ; ! 362: ! 363: tvdir: LEN EQ LONGINT = { ! 364: #if TRVEC ! 365: if( tvspec.tvlength > 0 ) ! 366: yyerror("illegal multiple LENGTH fields in the TV directive"); ! 367: tvspec.tvlength = (int) (*(long *) $3); ! 368: #else ! 369: yyerror("usage of unimplemented syntax"); ! 370: #endif ! 371: } ! 372: | RANGE LPAREN LONGINT COMMA LONGINT RPAREN = { ! 373: #if TRVEC ! 374: if( tvspec.tvrange[1] > 0 ) ! 375: yyerror("illegal multiple RANGE fields in the TV directive"); ! 376: if( tvspec.tvrange[0] < 0 || tvspec.tvrange[0] > tvspec.tvrange[1] ) ! 377: yyerror("illegal RANGE syntax: r[0]<0 or r[0]>r[1]"); ! 378: else { ! 379: tvspec.tvrange[0] = (int) (*(long *) $3); ! 380: tvspec.tvrange[1] = (int) (*(long *) $5); ! 381: } ! 382: #else ! 383: yyerror("usage of unimplemented syntax"); ! 384: #endif ! 385: } ! 386: | ASSIGN LPAREN slotlist RPAREN ! 387: ; ! 388: ! 389: tvfill : EQ NAME = { ! 390: #if TRVEC ! 391: #if FLEXNAMES ! 392: tvspec.tvfnfill = savefn($2); ! 393: #else ! 394: strncpy(tvspec.tvfnfill, $2, 8 ); ! 395: #endif ! 396: #else ! 397: yyerror("usage of unimplemented syntax"); ! 398: #endif ! 399: } ! 400: | /* empty */ ! 401: ; ! 402: ! 403: slotlist: slotspec ! 404: | slotlist com slotspec ! 405: | /* empty */ ! 406: ; ! 407: slotspec: NAME EQ LONGINT = { ! 408: #if TRVEC ! 409: if( (int) (*(long *) $3) == 0 ) ! 410: yyerror("illegal ASSIGN slot number (0)"); ! 411: if( tvslot1 == NULL ) ! 412: tvslot1 = tvslotn = (TVASSIGN *) myalloc(sizeof(TVASSIGN)); ! 413: else ! 414: tvslotn = tvslotn->nxtslot = (TVASSIGN *) myalloc(sizeof(TVASSIGN)); ! 415: #if FLEXNAMES ! 416: tvslotn->funname = savefn($1); ! 417: #else ! 418: strncpy(tvslotn->funname, $1, 8); ! 419: #endif ! 420: tvslotn->slot = (int) (*(long *) $3); ! 421: tvslotn->nxtslot = NULL; ! 422: #else ! 423: yyerror("usage of unimplemented syntax"); ! 424: #endif ! 425: } ! 426: ; ! 427: ! 428: opt_long : LONGINT = { ! 429: long org; ! 430: org = *(long *) $1; ! 431: #if TRVEC ! 432: chktvorg(org, &(tvspec.tvbndadr)); ! 433: #endif ! 434: } ! 435: | /* empty */ ! 436: ; ! 437: /*eject*/ ! 438: secspecs: SECTIONS LBRACE sglist RBRACE = ! 439: ; ! 440: ! 441: sglist: sec_or_grp ! 442: | sglist com sec_or_grp ! 443: ; ! 444: ! 445: sec_or_grp: scnspc ! 446: | groupspc ! 447: | flgstmt2 ! 448: ; ! 449: ! 450: seclist: scnspc ! 451: | seclist com scnspc ! 452: ; ! 453: ! 454: groupspc: grprfx LBRACE seclist RBRACE inclspc = { ! 455: listadd(l_AI,&bldoutsc,grptr); ! 456: grptr = NULL; ! 457: } ! 458: ; ! 459: ! 460: grprfx: GROUP opt_org opt_aln opt_block COLON = { ! 461: if ( $2 != NULL && $3 != NULL ) ! 462: yyerror("bonding excludes alignment"); ! 463: grptr = dfnscngrp(AIDFNGRP, (long *)$2, (long *)$3, (long *)$4); ! 464: strncpy( grptr->dfnscn.ainame, "*group*", 8 ); ! 465: } ! 466: ; ! 467: ! 468: flgstmt2: MINUS NAME = { ! 469: char *fp; ! 470: fp = $2; ! 471: if (fp[0] == 'l') /* library flag */ ! 472: library(fp); ! 473: else ! 474: yyerror("bad flag value in SECTIONS directive: -%s", $2); ! 475: } ! 476: ; ! 477: ! 478: scnspc: scnprfx LBRACE scnstmts RBRACE fillspc inclspc = { ! 479: if (aiptr == NULL) ! 480: goto scnerr; ! 481: aiptr->dfnscn.aifill = $5; ! 482: aiptr->dfnscn.aifillfg = fillflag; ! 483: listadd(l_AI,grptr ? &grptr->dfnscn.sectspec : &bldoutsc,aiptr); ! 484: if (grptr && $6) ! 485: yyerror("can not specify an owner for section within a group"); ! 486: aiptr = NULL; ! 487: } ! 488: | error = { ! 489: if (aiptr) ! 490: yyerror("section %s not built", aiptr->dfnscn.ainame); ! 491: scnerr: ! 492: aiptr = NULL; ! 493: } ! 494: ; ! 495: ! 496: scnprfx: NAME opt_org opt_aln opt_block opt_type COLON = { ! 497: secnum++; ! 498: if ( OKSCNNAME($1) == 0 ) ! 499: yyerror("%s is a reserved section name", $1); ! 500: if ( $2 != NULL && $3 != NULL ) ! 501: yyerror("bonding excludes alignment"); ! 502: aiptr = dfnscngrp(AIDFNSCN, (long *)$2, (long *)$3, (long *)$4); ! 503: if (grptr && aiptr->dfnscn.aibndadr != -1L) ! 504: yyerror("can not bond a section within a group"); ! 505: if (grptr && aiptr->dfnscn.aialign != 0L) ! 506: yyerror("can not align a section within a group"); ! 507: aiptr->dfnscn.aisctype = $5; ! 508: strncpy( aiptr->dfnscn.ainame, $1, 8 ); ! 509: } ! 510: ; ! 511: ! 512: opt_block: BLOCK LPAREN LONGINT RPAREN = { ! 513: $$ = $3; ! 514: } ! 515: | = { /* empty */ ! 516: $$ = NULL; ! 517: } ! 518: ; ! 519: ! 520: opt_org: LONGINT = { ! 521: $$ = $1; ! 522: } ! 523: | = { /* empty */ ! 524: $$ = NULL; ! 525: } ! 526: ; ! 527: ! 528: opt_aln: ALIGN LPAREN LONGINT RPAREN = { ! 529: $$ = $3; ! 530: } ! 531: | = { /* empty */ ! 532: $$ = NULL; ! 533: } ! 534: ; ! 535: ! 536: opt_type: LPAREN DSECT RPAREN = { ! 537: $$ = STYP_DSECT; ! 538: } ! 539: | LPAREN NOLOAD RPAREN = { ! 540: $$ = STYP_NOLOAD; ! 541: } ! 542: | LPAREN COPY RPAREN = { ! 543: $$ = STYP_COPY | STYP_DSECT; ! 544: } ! 545: | LPAREN INFO RPAREN = { ! 546: $$ = STYP_INFO | STYP_DSECT; ! 547: } ! 548: | = { /* empty */ ! 549: $$ = STYP_REG; ! 550: } ! 551: ; ! 552: ! 553: scnstmts: scnstmt ! 554: | scnstmts com scnstmt ! 555: | /* empty */ ! 556: ; ! 557: ! 558: scnstmt: fname insecspc ! 559: | flgstmt2 = { ! 560: bldadfil( ((ACTITEM *) ldfilist.tail)->ldlbry.aifilnam, aiptr ); ! 561: } ! 562: | assnment = { ! 563: bldexp($1,&aiptr->dfnscn.sectspec); ! 564: } ! 565: | error = { ! 566: in_y_exp = 0; ! 567: yyerror("statement ignored"); ! 568: for( tempi = lineno; ((int)yychar > 0) && (tempi == lineno) ; ) ! 569: yychar = yylex(); ! 570: if ((int) yychar <= 0) ! 571: lderror(2,0,NULL, "unexpected EOF"); ! 572: yyerrok; ! 573: yyclearin; ! 574: } ! 575: ; ! 576: ! 577: fname: filename = { ! 578: fnamptr = savefn($1); ! 579: nsecspcs = 0; ! 580: bldldfil(fnamptr,0); ! 581: afaiptr = bldadfil(fnamptr,aiptr); ! 582: } ! 583: ; ! 584: insecspc: LPAREN inseclist RPAREN fillspc = { ! 585: afaiptr->adfile.ainadscs = nsecspcs; ! 586: afaiptr->adfile.aifilflg = fillflag; ! 587: afaiptr->adfile.aifill2 = $4; ! 588: } ! 589: | /* empty */ ! 590: ; ! 591: ! 592: inseclist: NAME = { ! 593: nsecspcs++; ! 594: bldadscn($1,fnamptr,aiptr); ! 595: } ! 596: | inseclist com NAME = { ! 597: nsecspcs++; ! 598: bldadscn($3,fnamptr,aiptr); ! 599: } ! 600: ; ! 601: ! 602: inclspc: GT NAME = { ! 603: if (grptr) ! 604: strncpy( grptr->dfnscn.aiowname, $2, 8 ); ! 605: else ! 606: strncpy( aiptr->dfnscn.aiowname, $2, 8 ); ! 607: $$ = 1; ! 608: } ! 609: | GT attr = { ! 610: if (grptr) ! 611: grptr->dfnscn.aiattown = $2; ! 612: else ! 613: aiptr->dfnscn.aiattown = $2; ! 614: $$ = 1; ! 615: } ! 616: | = { /* empty */ ! 617: $$ = 0; ! 618: } ! 619: ; ! 620: ! 621: fillspc: EQ LONGINT = { ! 622: fillflag = 1; ! 623: $$ = (int) (*(long *)$2); ! 624: } ! 625: | = { /* empty */ ! 626: fillflag = 0; ! 627: $$ = 0; ! 628: } ! 629: | EQ error = { ! 630: yyerror("bad fill value"); ! 631: fillflag = 0; ! 632: yyerrok; ! 633: yyclearin; ! 634: $$ = 0; ! 635: } ! 636: ; ! 637: /*eject*/ ! 638: assnment: ename assnop expr exend = { ! 639: in_y_exp = 0; ! 640: if ( $2 == EQ ) ! 641: $$ = buildtree(EQ, $1, $3); ! 642: else { ! 643: ENODE *p,*ndp; ! 644: ndp = buildtree($2,$1,$3); ! 645: p = (ENODE *) myalloc(sizeof(ENODE)); ! 646: *p = *$1; ! 647: $$ = buildtree(EQ,p,ndp); ! 648: } ! 649: } ! 650: ; ! 651: ! 652: assnop: DIVEQ = { $$ = DIV; in_y_exp = TRUE; } ! 653: | EQ = { $$ = EQ; in_y_exp = TRUE; } ! 654: | MINUSEQ = { $$ = MINUS; in_y_exp = TRUE; } ! 655: | MULTEQ = { $$ = MULT; in_y_exp = TRUE; } ! 656: | PLUSEQ = { $$ = PLUS; in_y_exp = TRUE; } ! 657: ; ! 658: ! 659: expr: expr PLUS expr = { ! 660: bop: ! 661: $$ = buildtree($2,$1,$3); ! 662: } ! 663: | expr MINUS expr = { goto bop; } ! 664: | expr MULT expr = { goto bop; } ! 665: | expr DIV expr = { goto bop; } ! 666: | expr PC expr = { goto bop; } ! 667: | expr RSHIFT expr = { goto bop; } ! 668: | expr LSHIFT expr = { goto bop; } ! 669: | expr AND expr = { goto bop; } ! 670: | expr OR expr = { goto bop; } ! 671: | expr GT expr = { goto bop; } ! 672: | expr LT expr = { goto bop; } ! 673: | expr GE expr = { goto bop; } ! 674: | expr LE expr = { goto bop; } ! 675: | expr NE expr = { goto bop; } ! 676: | expr EQEQ expr = { goto bop; } ! 677: | expr ANDAND expr = { goto bop; } ! 678: | expr OROR expr = { goto bop; } ! 679: | term = { ! 680: $$ = $1; ! 681: } ! 682: ; ! 683: ! 684: exend: SEMICOL ! 685: | COMMA ! 686: | error = { ! 687: yyerror ("semicolon required after expression"); ! 688: } ! 689: ; ! 690: ! 691: term: LONGINT = { ! 692: $$ = cnstnode(*(long *) $1); ! 693: } ! 694: | ename = { ! 695: $$ = $1; ! 696: } ! 697: | MINUS term = { ! 698: $$ = buildtree(UMINUS,$2,NULL); ! 699: } ! 700: | NOT term = { ! 701: $$ = buildtree($1,$2,NULL); ! 702: } ! 703: | BNOT term = { ! 704: $$ = buildtree(BNOT,$1,NULL); ! 705: } ! 706: | ALIGN LPAREN expr RPAREN = { ! 707: $$ = buildtree($1,$3,NULL); ! 708: } ! 709: | PHY LPAREN ename RPAREN = { ! 710: $$ = buildtree($1,$3,NULL); ! 711: } ! 712: | LPAREN expr RPAREN = { ! 713: $$ = $2; ! 714: } ! 715: ; ! 716: ! 717: ename: NAME = { ! 718: $$ = symnode($1); ! 719: } ! 720: | DOT = { ! 721: $$ = symnode(NULL); ! 722: } ! 723: ; ! 724: /*eject*/ ! 725: filename: NAME = { ! 726: $$ = $1; ! 727: } ! 728: | FILENAME = { ! 729: $$ = $1; ! 730: } ! 731: ; ! 732: /*eject*/ ! 733: flagstmt: MINUS filename = { ! 734: pflags($2, TRUE); ! 735: } ! 736: ; ! 737: %% ! 738: /*eject*/ ! 739: /*VARARGS*/ ! 740: yyerror(format, a1, a2, a3, a4) ! 741: char *format; ! 742: { ! 743: ! 744: /* ! 745: * Issue a parsing error message ! 746: */ ! 747: ! 748: char *p; ! 749: ! 750: p = sname(curfilnm); /* strip off directories from path name */ ! 751: ! 752: /* ! 753: * For any purely YACC-generated error, also print out the current ! 754: * line, up to the point of the error ! 755: */ ! 756: ! 757: if( strcmp(format, "syntax error") == 0 ) ! 758: lderror(1, lineno, p, "%s : scanned line = (%s)", format, inline, a1, a2 ); ! 759: else ! 760: lderror(1, lineno, p, format, a1, a2, a3, a4); ! 761: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.