|
|
1.1 ! root 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.4 (Berkeley) 1/3/88 ! 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.4 1/3/88"; */ ! 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.4 1/3/88"; ! 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, lineof($1.i_entry)), ! 221: constant(lineof($3.i_entry), $2.cptr, $4.tr_entry); ! 222: | ! 223: const_decl YID '=' const ';' ! 224: = constant(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: ;
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.