1: /* 2: * Copyright (c) 1980 Regents of the University of California. 3: * All rights reserved. The Berkeley software License Agreement 4: * specifies the terms and conditions for redistribution. 5: * 6: * @(#)pas.y 5.2 (Berkeley) 6/20/85 7: */ 8: 9: /* 10: * Yacc grammar for UNIX Pascal 11: * 12: * This grammar is processed by the commands in the shell script 13: * "gram" to yield parse tables and semantic routines in the file 14: * "y.tab.c" and a header defining the lexical tokens in "yy.h". 15: * 16: * In order for the syntactic error recovery possible with this 17: * grammar to work, the grammar must be processed by a yacc which 18: * has been modified to fully enumerate possibilities in states 19: * which involve the symbol "error". 20: * The parser used for Pascal also uses a different encoding of 21: * the test entries in the action table which speeds the parse. 22: * A version of yacc which will work for Pascal is included on 23: * the distribution table as "eyacc". 24: * 25: * The "gram" script also makes the following changes to the "y.tab.c" 26: * file: 27: * 28: * 1) Causes yyval to be declared int *. 29: * 30: * 2) Loads the variable yypv into a register as yyYpv so that 31: * the arguments $1, ... are available as yyYpv[1] etc. 32: * This produces much smaller code in the semantic actions. 33: * 34: * 3) Deletes the unused array yysterm. 35: * 36: * 4) Moves the declarations up to the flag line containing 37: * '##' to the file yy.h so that the routines which use 38: * these "magic numbers" don't have to all be compiled at 39: * the same time. 40: * 41: * 5) Creates the semantic restriction checking routine yyEactr 42: * by processing action lines containing `@@'. 43: * 44: * This compiler uses a different version of the yacc parser, a 45: * different yyerror which is called yerror, and requires more 46: * lookahead sets than normally provided by yacc. 47: * 48: * Source for the yacc used with this grammar is included on 49: * distribution tapes. 50: */ 51: 52: /* 53: * TERMINAL DECLARATIONS 54: * 55: * Some of the terminal declarations are out of the most natural 56: * alphabetic order because the error recovery 57: * will guess the first of equal cost non-terminals. 58: * This makes, e.g. YTO preferable to YDOWNTO. 59: */ 60: 61: %term 62: YAND YARRAY YBEGIN YCASE 63: YCONST YDIV YDO YDOTDOT 64: YTO YELSE YEND YFILE 65: YFOR YFORWARD YPROCEDURE YGOTO 66: YID YIF YIN YINT 67: YLABEL YMOD YNOT YNUMB 68: YOF YOR YPACKED YNIL 69: YFUNCTION YPROG YRECORD YREPEAT 70: YSET YSTRING YTHEN YDOWNTO 71: YTYPE YUNTIL YVAR YWHILE 72: YWITH YBINT YOCT YHEX 73: YCASELAB YILLCH YEXTERN YLAST 74: 75: /* 76: * PRECEDENCE DECLARATIONS 77: * 78: * Highest precedence is the unary logical NOT. 79: * Next are the multiplying operators, signified by '*'. 80: * Lower still are the binary adding operators, signified by '+'. 81: * Finally, at lowest precedence and non-associative are the relationals. 82: */ 83: 84: %binary '<' '=' '>' YIN 85: %left '+' '-' YOR '|' 86: %left UNARYSIGN 87: %left '*' '/' YDIV YMOD YAND '&' 88: %left YNOT 89: 90: %{ 91: /* 92: * GLOBALS FOR ACTIONS 93: */ 94: 95: /* Copyright (c) 1979 Regents of the University of California */ 96: 97: /* static char sccsid[] = "@(#)pas.y 5.2 6/20/85"; */ 98: 99: /* 100: * The following line marks the end of the yacc 101: * Constant definitions which are removed from 102: * y.tab.c and placed in the file y.tab.h. 103: */ 104: ## 105: /* Copyright (c) 1979 Regents of the University of California */ 106: 107: static char sccsid[] = "@(#)pas.y 5.2 6/20/85"; 108: 109: #include "whoami.h" 110: #include "0.h" 111: #include "tree_ty.h" /* must be included for yy.h */ 112: #include "yy.h" 113: #include "tree.h" 114: 115: #ifdef PI 116: #define lineof(l) l 117: #define line2of(l) l 118: #endif 119: 120: %} 121: 122: %% 123: 124: /* 125: * PRODUCTIONS 126: */ 127: 128: goal: 129: prog_hedr decls block '.' 130: = funcend($1.nl_entry, $3.tr_entry, lineof($4.i_entry)); 131: | 132: decls 133: = segend(); 134: ; 135: 136: 137: prog_hedr: 138: YPROG YID '(' id_list ')' ';' 139: = $$.nl_entry = funcbody(funchdr(tree5(T_PROG, lineof($1.i_entry), $2.tr_entry, fixlist($4.tr_entry), TR_NIL))); 140: | 141: YPROG YID ';' 142: = $$.nl_entry = funcbody(funchdr(tree5(T_PROG, lineof($1.i_entry), $2.tr_entry, TR_NIL, TR_NIL))); 143: | 144: YPROG error 145: = { 146: yyPerror("Malformed program statement", PPROG); 147: /* 148: * Should make a program statement 149: * with "input" and "output" here. 150: */ 151: $$.nl_entry = funcbody(funchdr(tree5(T_PROG, lineof($1.i_entry), TR_NIL, TR_NIL, TR_NIL))); 152: } 153: ; 154: block: 155: YBEGIN stat_list YEND 156: = { 157: $$.tr_entry = tree3(T_BSTL, lineof($1.i_entry), fixlist($2.tr_entry)); 158: if ($3.i_entry < 0) 159: brerror($1.i_entry, "begin"); 160: } 161: ; 162: 163: 164: /* 165: * DECLARATION PART 166: */ 167: decls: 168: decls decl 169: = trfree(); 170: | 171: decls error 172: = { 173: constend(), typeend(), varend(), trfree(); 174: yyPerror("Malformed declaration", PDECL); 175: } 176: | 177: /* lambda */ 178: = trfree(); 179: ; 180: 181: decl: 182: labels 183: | 184: const_decl 185: = constend(); 186: | 187: type_decl 188: = typeend(); 189: | 190: var_decl 191: = varend(); 192: | 193: proc_decl 194: ; 195: 196: /* 197: * LABEL PART 198: */ 199: 200: labels: 201: YLABEL label_decl ';' 202: = label(fixlist($2.tr_entry), lineof($1.i_entry)); 203: ; 204: label_decl: 205: YINT 206: = $$.tr_entry = newlist($1.i_entry == NIL ? TR_NIL : 207: (struct tnode *) *hash($1.cptr, 1)); 208: | 209: label_decl ',' YINT 210: = $$.tr_entry = addlist($1.tr_entry, $3.i_entry == NIL ? 211: TR_NIL : (struct tnode *) *hash($3.cptr, 1)); 212: ; 213: 214: /* 215: * CONST PART 216: */ 217: 218: const_decl: 219: YCONST YID '=' const ';' 220: = constbeg($1.i_entry), const(lineof($3.i_entry), $2.cptr, 221: $4.tr_entry); 222: | 223: const_decl YID '=' const ';' 224: = const(lineof($3.i_entry), $2.cptr, $4.tr_entry); 225: | 226: YCONST error 227: = { 228: constbeg($1.i_entry); 229: Cerror: 230: yyPerror("Malformed const declaration", PDECL); 231: } 232: | 233: const_decl error 234: = goto Cerror; 235: ; 236: 237: /* 238: * TYPE PART 239: */ 240: 241: type_decl: 242: YTYPE YID '=' type ';' 243: = typebeg($1.i_entry, line2of($2.i_entry)), type(lineof($3.i_entry), $2.cptr, $4.tr_entry); 244: | 245: type_decl YID '=' type ';' 246: = type(lineof($3.i_entry), $2.cptr, $4.tr_entry); 247: | 248: YTYPE error 249: = { 250: typebeg($1.i_entry, line2of($1.i_entry)); 251: Terror: 252: yyPerror("Malformed type declaration", PDECL); 253: } 254: | 255: type_decl error 256: = goto Terror; 257: ; 258: 259: /* 260: * VAR PART 261: */ 262: 263: var_decl: 264: YVAR id_list ':' type ';' 265: = varbeg($1.i_entry, line2of($3.i_entry)), var(lineof($3.i_entry), fixlist($2.tr_entry), $4.tr_entry); 266: | 267: var_decl id_list ':' type ';' 268: = var(lineof($3.i_entry), fixlist($2.tr_entry), $4.tr_entry); 269: | 270: YVAR error 271: = { 272: varbeg($1.i_entry, line2of($1.i_entry)); 273: Verror: 274: yyPerror("Malformed var declaration", PDECL); 275: } 276: | 277: var_decl error 278: = goto Verror; 279: ; 280: 281: /* 282: * PROCEDURE AND FUNCTION DECLARATION PART 283: */ 284: 285: proc_decl: 286: phead YFORWARD ';' 287: = funcfwd($1.nl_entry); 288: | 289: phead YEXTERN ';' 290: = (void) funcext($1.nl_entry); 291: | 292: pheadres decls block ';' 293: = funcend($1.nl_entry, $3.tr_entry, lineof($4.i_entry)); 294: | 295: phead error 296: ; 297: pheadres: 298: phead 299: = (void) funcbody($1.nl_entry); 300: ; 301: phead: 302: porf YID params ftype ';' 303: = $$.nl_entry = funchdr(tree5($1.i_entry, lineof($5.i_entry), 304: $2.tr_entry, $3.tr_entry, $4.tr_entry)); 305: ; 306: porf: 307: YPROCEDURE 308: = $$.i_entry = T_PDEC; 309: | 310: YFUNCTION 311: = $$.i_entry = T_FDEC; 312: ; 313: params: 314: '(' param_list ')' 315: = $$.tr_entry = fixlist($2.tr_entry); 316: | 317: /* lambda */ 318: = $$.tr_entry = TR_NIL; 319: ; 320: 321: /* 322: * PARAMETERS 323: */ 324: 325: param: 326: id_list ':' type 327: = $$.tr_entry = tree3(T_PVAL, (int) fixlist($1.tr_entry), $3.tr_entry); 328: | 329: YVAR id_list ':' type 330: = $$.tr_entry = tree3(T_PVAR, (int) fixlist($2.tr_entry), $4.tr_entry); 331: | 332: YFUNCTION id_list params ftype 333: = $$.tr_entry = tree5(T_PFUNC, (int) fixlist($2.tr_entry), 334: $4.tr_entry, $3.tr_entry, 335: (struct tnode *) lineof($1.i_entry)); 336: | 337: YPROCEDURE id_list params ftype 338: = $$.tr_entry = tree5(T_PPROC, (int) fixlist($2.tr_entry), 339: $4.tr_entry, $3.tr_entry, 340: (struct tnode *) lineof($1.i_entry)); 341: ; 342: ftype: 343: ':' type 344: = $$ = $2; 345: | 346: /* lambda */ 347: = $$.tr_entry = TR_NIL; 348: ; 349: param_list: 350: param 351: = $$.tr_entry = newlist($1.tr_entry); 352: | 353: param_list ';' param 354: = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry); 355: ; 356: 357: /* 358: * CONSTANTS 359: */ 360: 361: const: 362: YSTRING 363: = $$.tr_entry = tree2(T_CSTRNG, $1.i_entry); 364: | 365: number 366: | 367: '+' number 368: = $$.tr_entry = tree2(T_PLUSC, $2.i_entry); 369: | 370: '-' number 371: = $$.tr_entry = tree2(T_MINUSC, $2.i_entry); 372: ; 373: number: 374: const_id 375: = $$.tr_entry = tree2(T_ID, $1.i_entry); 376: | 377: YINT 378: = $$.tr_entry = tree2(T_CINT, $1.i_entry); 379: | 380: YBINT 381: = $$.tr_entry = tree2(T_CBINT, $1.i_entry); 382: | 383: YNUMB 384: = $$.tr_entry = tree2(T_CFINT, $1.i_entry); 385: ; 386: const_list: 387: const 388: = $$.tr_entry = newlist($1.tr_entry); 389: | 390: const_list ',' const 391: = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry); 392: ; 393: 394: /* 395: * TYPES 396: */ 397: 398: type: 399: simple_type 400: | 401: '^' YID 402: = $$.tr_entry = tree3(T_TYPTR, lineof($1.i_entry), tree2(T_ID, 403: $2.i_entry)); 404: | 405: struct_type 406: | 407: YPACKED struct_type 408: = $$.tr_entry = tree3(T_TYPACK, lineof($1.i_entry), $2.tr_entry); 409: ; 410: simple_type: 411: type_id 412: | 413: '(' id_list ')' 414: = $$.tr_entry = tree3(T_TYSCAL, lineof($1.i_entry), fixlist($2.tr_entry)); 415: | 416: const YDOTDOT const 417: = $$.tr_entry = tree4(T_TYRANG, lineof($2.i_entry), $1.tr_entry, 418: $3.tr_entry); 419: ; 420: struct_type: 421: YARRAY '[' simple_type_list ']' YOF type 422: = $$.tr_entry = tree4(T_TYARY, lineof($1.i_entry), 423: fixlist($3.tr_entry), $6.tr_entry); 424: | 425: YFILE YOF type 426: = $$.tr_entry = tree3(T_TYFILE, lineof($1.i_entry), $3.tr_entry); 427: | 428: YSET YOF simple_type 429: = $$.tr_entry = tree3(T_TYSET, lineof($1.i_entry), $3.tr_entry); 430: | 431: YRECORD field_list YEND 432: = { 433: $$.tr_entry = setuptyrec( lineof( $1.i_entry ) , $2.tr_entry); 434: if ($3.i_entry < 0) 435: brerror($1.i_entry, "record"); 436: } 437: ; 438: simple_type_list: 439: simple_type 440: = $$.tr_entry = newlist($1.tr_entry); 441: | 442: simple_type_list ',' simple_type 443: = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry); 444: ; 445: 446: /* 447: * RECORD TYPE 448: */ 449: field_list: 450: fixed_part variant_part 451: = $$.tr_entry = tree4(T_FLDLST, lineof(NIL), 452: fixlist($1.tr_entry), $2.tr_entry); 453: ; 454: fixed_part: 455: field 456: = $$.tr_entry = newlist($1.tr_entry); 457: | 458: fixed_part ';' field 459: = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry); 460: | 461: fixed_part error 462: = yyPerror("Malformed record declaration", PDECL); 463: ; 464: field: 465: /* lambda */ 466: = $$.tr_entry = TR_NIL; 467: | 468: id_list ':' type 469: = $$.tr_entry = tree4(T_RFIELD, lineof($2.i_entry), 470: fixlist($1.tr_entry), $3.tr_entry); 471: ; 472: 473: variant_part: 474: /* lambda */ 475: = $$.tr_entry = TR_NIL; 476: | 477: YCASE type_id YOF variant_list 478: = $$.tr_entry = tree5(T_TYVARPT, lineof($1.i_entry), TR_NIL, 479: $2.tr_entry, fixlist($4.tr_entry)); 480: | 481: YCASE YID ':' type_id YOF variant_list 482: = $$.tr_entry = tree5(T_TYVARPT, lineof($1.i_entry), 483: $2.tr_entry, $4.tr_entry, 484: fixlist($6.tr_entry)); 485: ; 486: variant_list: 487: variant 488: = $$.tr_entry = newlist($1.tr_entry); 489: | 490: variant_list ';' variant 491: = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry); 492: | 493: variant_list error 494: = yyPerror("Malformed record declaration", PDECL); 495: ; 496: variant: 497: /* lambda */ 498: = $$.tr_entry = TR_NIL; 499: | 500: const_list ':' '(' field_list ')' 501: = $$.tr_entry = tree4(T_TYVARNT,lineof($2.i_entry), fixlist($1.tr_entry), 502: $4.tr_entry); 503: ; 504: 505: /* 506: * STATEMENT LIST 507: */ 508: 509: stat_list: 510: stat 511: = $$.tr_entry = newlist($1.tr_entry); 512: | 513: stat_lsth stat 514: = { 515: if ((p = $1.tr_entry) != TR_NIL && (q = p->list_node.list)->tag == T_IFX) { 516: q->tag = T_IFEL; 517: q->if_node.else_stmnt = $2.tr_entry; 518: } else 519: $$.tr_entry= addlist($1.tr_entry, $2.tr_entry); 520: } 521: ; 522: 523: stat_lsth: 524: stat_list ';' 525: = if ((q = $1.tr_entry) != TR_NIL && (p = q->list_node.list) != TR_NIL && p->tag == T_IF) { 526: if (yychar < 0) 527: yychar = yylex(); 528: if (yyshifts >= 2 && yychar == YELSE) { 529: recovered(); 530: copy((char *) (&Y), (char *) (&OY), sizeof Y); 531: yerror("Deleted ';' before keyword else"); 532: yychar = yylex(); 533: p->tag = T_IFX; 534: } 535: } 536: ; 537: 538: /* 539: * CASE STATEMENT LIST 540: */ 541: 542: cstat_list: 543: cstat 544: = $$.tr_entry = newlist($1.tr_entry); 545: | 546: cstat_list ';' cstat 547: = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry); 548: | 549: error 550: = { 551: $$.tr_entry = TR_NIL; 552: Kerror: 553: yyPerror("Malformed statement in case", PSTAT); 554: } 555: | 556: cstat_list error 557: = goto Kerror; 558: ; 559: 560: cstat: 561: const_list ':' stat 562: = $$.tr_entry = tree4(T_CSTAT, lineof($2.i_entry), 563: fixlist($1.tr_entry), $3.tr_entry); 564: | 565: YCASELAB stat 566: = $$.tr_entry = tree4(T_CSTAT, lineof($1.i_entry), TR_NIL, 567: $2.tr_entry); 568: | 569: /* lambda */ 570: = $$.tr_entry = TR_NIL; 571: ; 572: 573: /* 574: * STATEMENT 575: */ 576: 577: stat: 578: /* lambda */ 579: = $$.tr_entry = TR_NIL; 580: | 581: YINT ':' stat 582: = $$.tr_entry = tree4(T_LABEL, lineof($2.i_entry), 583: $1.tr_entry == TR_NIL ? TR_NIL : 584: (struct tnode *) *hash($1.cptr, 1), $3.tr_entry); 585: | 586: proc_id 587: = $$.tr_entry = tree4(T_PCALL, lineof(yyline), $1.tr_entry, 588: TR_NIL); 589: | 590: proc_id '(' wexpr_list ')' 591: = $$.tr_entry = tree4(T_PCALL, lineof($2.i_entry), $1.tr_entry, 592: fixlist($3.tr_entry)); 593: | 594: YID error 595: = goto NSerror; 596: | 597: assign 598: | 599: YBEGIN stat_list YEND 600: = { 601: $$.tr_entry = tree3(T_BLOCK, lineof($1.i_entry), 602: fixlist($2.tr_entry)); 603: if ($3.i_entry < 0) 604: brerror($1.i_entry, "begin"); 605: } 606: | 607: YCASE expr YOF cstat_list YEND 608: = { 609: $$.tr_entry = tree4(T_CASE, lineof($1.i_entry), 610: $2.tr_entry, fixlist($4.tr_entry)); 611: if ($5.i_entry < 0) 612: brerror($1.i_entry, "case"); 613: } 614: | 615: YWITH var_list YDO stat 616: = $$.tr_entry = tree4(T_WITH, lineof($1.i_entry), 617: fixlist($2.tr_entry), $4.tr_entry); 618: | 619: YWHILE expr YDO stat 620: = $$.tr_entry = tree4(T_WHILE, lineof($1.i_entry), $2.tr_entry, 621: $4.tr_entry); 622: | 623: YREPEAT stat_list YUNTIL expr 624: = $$.tr_entry = tree4(T_REPEAT, lineof($3.i_entry), 625: fixlist($2.tr_entry), $4.tr_entry); 626: | 627: YFOR assign YTO expr YDO stat 628: = $$.tr_entry = tree5(T_FORU, lineof($1.i_entry), $2.tr_entry, 629: $4.tr_entry, $6.tr_entry); 630: | 631: YFOR assign YDOWNTO expr YDO stat 632: = $$.tr_entry = tree5(T_FORD, lineof($1.i_entry), $2.tr_entry, 633: $4.tr_entry, $6.tr_entry); 634: | 635: YGOTO YINT 636: = $$.tr_entry = tree3(T_GOTO, lineof($1.i_entry), 637: (struct tnode *) *hash($2.cptr, 1)); 638: | 639: YIF expr YTHEN stat 640: = $$.tr_entry = tree5(T_IF, lineof($1.i_entry), $2.tr_entry, 641: $4.tr_entry, TR_NIL); 642: | 643: YIF expr YTHEN stat YELSE stat 644: = $$.tr_entry = tree5(T_IFEL, lineof($1.i_entry), $2.tr_entry, 645: $4.tr_entry, $6.tr_entry); 646: | 647: error 648: = { 649: NSerror: 650: $$.tr_entry = TR_NIL; 651: yyPerror("Malformed statement", PSTAT); 652: } 653: ; 654: assign: 655: variable ':' '=' expr 656: = $$.tr_entry = tree4(T_ASGN, lineof($2.i_entry), $1.tr_entry, 657: $4.tr_entry); 658: ; 659: 660: /* 661: * EXPRESSION 662: */ 663: 664: expr: 665: error 666: = { 667: NEerror: 668: $$.tr_entry = TR_NIL; 669: yyPerror("Missing/malformed expression", PEXPR); 670: } 671: | 672: expr relop expr %prec '<' 673: = $$.tr_entry = tree4($2.i_entry, 674: $1.tr_entry->expr_node.const_tag == SAWCON ? 675: $3.tr_entry->expr_node.const_tag : 676: $1.tr_entry->expr_node.const_tag, 677: $1.tr_entry, $3.tr_entry); 678: | 679: '+' expr %prec UNARYSIGN 680: = $$.tr_entry = tree3(T_PLUS, $2.tr_entry->expr_node.const_tag, 681: $2.tr_entry); 682: | 683: '-' expr %prec UNARYSIGN 684: = $$.tr_entry = tree3(T_MINUS, $2.tr_entry->expr_node.const_tag, 685: $2.tr_entry); 686: | 687: expr addop expr %prec '+' 688: = $$.tr_entry = tree4($2.i_entry, 689: $1.tr_entry->expr_node.const_tag == SAWCON ? 690: $3.tr_entry->expr_node.const_tag : 691: $1.tr_entry->expr_node.const_tag, $1.tr_entry, 692: $3.tr_entry); 693: | 694: expr divop expr %prec '*' 695: = $$.tr_entry = tree4($2.i_entry, 696: $1.tr_entry->expr_node.const_tag == SAWCON ? 697: $3.tr_entry->expr_node.const_tag : 698: $1.tr_entry->expr_node.const_tag, $1.tr_entry, 699: $3.tr_entry); 700: | 701: YNIL 702: = $$.tr_entry = tree2(T_NIL, NOCON); 703: | 704: YSTRING 705: = $$.tr_entry = tree3(T_STRNG, SAWCON, $1.tr_entry); 706: | 707: YINT 708: = $$.tr_entry = tree3(T_INT, NOCON, $1.tr_entry); 709: | 710: YBINT 711: = $$.tr_entry = tree3(T_BINT, NOCON, $1.tr_entry); 712: | 713: YNUMB 714: = $$.tr_entry = tree3(T_FINT, NOCON, $1.tr_entry); 715: | 716: variable 717: | 718: YID error 719: = goto NEerror; 720: | 721: func_id '(' wexpr_list ')' 722: = $$.tr_entry = tree4(T_FCALL, NOCON, $1.tr_entry, 723: fixlist($3.tr_entry)); 724: | 725: '(' expr ')' 726: = $$.tr_entry = $2.tr_entry; 727: | 728: negop expr %prec YNOT 729: = $$.tr_entry = tree3(T_NOT, NOCON, $2.tr_entry); 730: | 731: '[' element_list ']' 732: = $$.tr_entry = tree3(T_CSET, SAWCON, fixlist($2.tr_entry)); 733: | 734: '[' ']' 735: = $$.tr_entry = tree3(T_CSET, SAWCON, TR_NIL); 736: ; 737: 738: element_list: 739: element 740: = $$.tr_entry = newlist($1.tr_entry); 741: | 742: element_list ',' element 743: = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry); 744: ; 745: element: 746: expr 747: | 748: expr YDOTDOT expr 749: = $$.tr_entry = tree3(T_RANG, $1.i_entry, $3.tr_entry); 750: ; 751: 752: /* 753: * QUALIFIED VARIABLES 754: */ 755: 756: variable: 757: YID 758: = { 759: @@ return (identis(var, VAR)); 760: $$.tr_entry = setupvar($1.cptr, TR_NIL); 761: } 762: | 763: qual_var 764: = $1.tr_entry->var_node.qual = 765: fixlist($1.tr_entry->var_node.qual); 766: ; 767: qual_var: 768: array_id '[' expr_list ']' 769: = $$.tr_entry = setupvar($1.cptr, tree2(T_ARY, 770: (int) fixlist($3.tr_entry))); 771: | 772: qual_var '[' expr_list ']' 773: = $1.tr_entry->var_node.qual = 774: addlist($1.tr_entry->var_node.qual, 775: tree2(T_ARY, (int) fixlist($3.tr_entry))); 776: | 777: record_id '.' field_id 778: = $$.tr_entry = setupvar($1.cptr, setupfield($3.tr_entry, 779: TR_NIL)); 780: | 781: qual_var '.' field_id 782: = $1.tr_entry->var_node.qual = 783: addlist($1.tr_entry->var_node.qual, 784: setupfield($3.tr_entry, TR_NIL)); 785: | 786: ptr_id '^' 787: = $$.tr_entry = setupvar($1.cptr, tree1(T_PTR)); 788: | 789: qual_var '^' 790: = $1.tr_entry->var_node.qual = 791: addlist($1.tr_entry->var_node.qual, tree1(T_PTR)); 792: ; 793: 794: /* 795: * Expression with write widths 796: */ 797: wexpr: 798: expr 799: | 800: expr ':' expr 801: = $$.tr_entry = tree4(T_WEXP, $1.i_entry, $3.tr_entry, TR_NIL); 802: | 803: expr ':' expr ':' expr 804: = $$.tr_entry = tree4(T_WEXP, $1.i_entry, $3.tr_entry, 805: $5.tr_entry); 806: | 807: expr octhex 808: = $$.tr_entry = tree4(T_WEXP, $1.i_entry, TR_NIL, $2.tr_entry); 809: | 810: expr ':' expr octhex 811: = $$.tr_entry = tree4(T_WEXP, $1.i_entry, $3.tr_entry, 812: $4.tr_entry); 813: ; 814: octhex: 815: YOCT 816: = $$.i_entry = OCT; 817: | 818: YHEX 819: = $$.i_entry = HEX; 820: ; 821: 822: expr_list: 823: expr 824: = $$.tr_entry = newlist($1.tr_entry); 825: | 826: expr_list ',' expr 827: = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry); 828: ; 829: 830: wexpr_list: 831: wexpr 832: = $$.tr_entry = newlist($1.tr_entry); 833: | 834: wexpr_list ',' wexpr 835: = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry); 836: ; 837: 838: /* 839: * OPERATORS 840: */ 841: 842: relop: 843: '=' = $$.i_entry = T_EQ; 844: | 845: '<' = $$.i_entry = T_LT; 846: | 847: '>' = $$.i_entry = T_GT; 848: | 849: '<' '>' = $$.i_entry = T_NE; 850: | 851: '<' '=' = $$.i_entry = T_LE; 852: | 853: '>' '=' = $$.i_entry = T_GE; 854: | 855: YIN = $$.i_entry = T_IN; 856: ; 857: addop: 858: '+' = $$.i_entry = T_ADD; 859: | 860: '-' = $$.i_entry = T_SUB; 861: | 862: YOR = $$.i_entry = T_OR; 863: | 864: '|' = $$.i_entry = T_OR; 865: ; 866: divop: 867: '*' = $$.i_entry = T_MULT; 868: | 869: '/' = $$.i_entry = T_DIVD; 870: | 871: YDIV = $$.i_entry = T_DIV; 872: | 873: YMOD = $$.i_entry = T_MOD; 874: | 875: YAND = $$.i_entry = T_AND; 876: | 877: '&' = $$.i_entry = T_AND; 878: ; 879: 880: negop: 881: YNOT 882: | 883: '~' 884: ; 885: 886: /* 887: * LISTS 888: */ 889: 890: var_list: 891: variable 892: = $$.tr_entry = newlist($1.tr_entry); 893: | 894: var_list ',' variable 895: = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry); 896: ; 897: 898: id_list: 899: YID 900: = $$.tr_entry = newlist($1.tr_entry); 901: | 902: id_list ',' YID 903: = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry); 904: ; 905: 906: /* 907: * Identifier productions with semantic restrictions 908: * 909: * For these productions, the characters @@ signify 910: * that the associated C statement is to provide 911: * the semantic restriction for this reduction. 912: * These lines are made into a procedure yyEactr, similar to 913: * yyactr, which determines whether the corresponding reduction 914: * is permitted, or whether an error is to be signaled. 915: * A zero return from yyEactr is considered an error. 916: * YyEactr is called with an argument "var" giving the string 917: * name of the variable in question, essentially $1, although 918: * $1 will not work because yyEactr is called from loccor in 919: * the recovery routines. 920: */ 921: 922: const_id: 923: YID 924: = @@ return (identis(var, CONST)); 925: ; 926: type_id: 927: YID 928: = { 929: @@ return (identis(var, TYPE)); 930: $$.tr_entry = tree3(T_TYID, lineof(yyline), $1.tr_entry); 931: } 932: ; 933: var_id: 934: YID 935: = @@ return (identis(var, VAR)); 936: ; 937: array_id: 938: YID 939: = @@ return (identis(var, ARRAY)); 940: ; 941: ptr_id: 942: YID 943: = @@ return (identis(var, PTRFILE)); 944: ; 945: record_id: 946: YID 947: = @@ return (identis(var, RECORD)); 948: ; 949: field_id: 950: YID 951: = @@ return (identis(var, FIELD)); 952: ; 953: proc_id: 954: YID 955: = @@ return (identis(var, PROC)); 956: ; 957: func_id: 958: YID 959: = @@ return (identis(var, FUNC)); 960: ;