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