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 2.1 02/08/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 2.1 02/08/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 ':' vtype 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 vtype: 344 type_id 345 | 346 c_ary 347 ; 348 c_ary: 349 YARRAY '[' i_type_list ']' YOF vtype 350 = $$.tr_entry = tree4(T_TYCARY, lineof($1.i_entry), 351 fixlist($3.tr_entry), $6.tr_entry); 352 ; 353 i_type_list: 354 i_type 355 = $$.tr_entry = newlist($1.tr_entry); 356 | 357 i_type_list ';' i_type 358 = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry); 359 ; 360 i_type: 361 YID YDOTDOT YID ':' type_id 362 = $$.tr_entry = tree5(T_TYCRANG,lineof($2.i_entry), $1.tr_entry, 363 $3.tr_entry, $5.tr_entry); 364 ; 365 param_list: 366 param 367 = $$.tr_entry = newlist($1.tr_entry); 368 | 369 param_list ';' param 370 = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry); 371 ; 372 373 374 /* 375 * CONSTANTS 376 */ 377 378 const: 379 YSTRING 380 = $$.tr_entry = tree2(T_CSTRNG, $1.i_entry); 381 | 382 number 383 | 384 '+' number 385 = $$.tr_entry = tree2(T_PLUSC, $2.i_entry); 386 | 387 '-' number 388 = $$.tr_entry = tree2(T_MINUSC, $2.i_entry); 389 ; 390 number: 391 const_id 392 = $$.tr_entry = tree2(T_ID, $1.i_entry); 393 | 394 YINT 395 = $$.tr_entry = tree2(T_CINT, $1.i_entry); 396 | 397 YBINT 398 = $$.tr_entry = tree2(T_CBINT, $1.i_entry); 399 | 400 YNUMB 401 = $$.tr_entry = tree2(T_CFINT, $1.i_entry); 402 ; 403 const_list: 404 const 405 = $$.tr_entry = newlist($1.tr_entry); 406 | 407 const_list ',' const 408 = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry); 409 ; 410 411 /* 412 * TYPES 413 */ 414 415 type: 416 simple_type 417 | 418 '^' YID 419 = $$.tr_entry = tree3(T_TYPTR, lineof($1.i_entry), tree2(T_ID, 420 $2.i_entry)); 421 | 422 struct_type 423 | 424 YPACKED struct_type 425 = $$.tr_entry = tree3(T_TYPACK, lineof($1.i_entry), $2.tr_entry); 426 ; 427 simple_type: 428 type_id 429 | 430 '(' id_list ')' 431 = $$.tr_entry = tree3(T_TYSCAL, lineof($1.i_entry), fixlist($2.tr_entry)); 432 | 433 const YDOTDOT const 434 = $$.tr_entry = tree4(T_TYRANG, lineof($2.i_entry), $1.tr_entry, 435 $3.tr_entry); 436 ; 437 struct_type: 438 YARRAY '[' simple_type_list ']' YOF type 439 = $$.tr_entry = tree4(T_TYARY, lineof($1.i_entry), 440 fixlist($3.tr_entry), $6.tr_entry); 441 | 442 YFILE YOF type 443 = $$.tr_entry = tree3(T_TYFILE, lineof($1.i_entry), $3.tr_entry); 444 | 445 YSET YOF simple_type 446 = $$.tr_entry = tree3(T_TYSET, lineof($1.i_entry), $3.tr_entry); 447 | 448 YRECORD field_list YEND 449 = { 450 $$.tr_entry = setuptyrec( lineof( $1.i_entry ) , $2.tr_entry); 451 if ($3.i_entry < 0) 452 brerror($1.i_entry, "record"); 453 } 454 ; 455 simple_type_list: 456 simple_type 457 = $$.tr_entry = newlist($1.tr_entry); 458 | 459 simple_type_list ',' simple_type 460 = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry); 461 ; 462 463 /* 464 * RECORD TYPE 465 */ 466 field_list: 467 fixed_part variant_part 468 = $$.tr_entry = tree4(T_FLDLST, lineof(NIL), 469 fixlist($1.tr_entry), $2.tr_entry); 470 ; 471 fixed_part: 472 field 473 = $$.tr_entry = newlist($1.tr_entry); 474 | 475 fixed_part ';' field 476 = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry); 477 | 478 fixed_part error 479 = yyPerror("Malformed record declaration", PDECL); 480 ; 481 field: 482 /* lambda */ 483 = $$.tr_entry = TR_NIL; 484 | 485 id_list ':' type 486 = $$.tr_entry = tree4(T_RFIELD, lineof($2.i_entry), 487 fixlist($1.tr_entry), $3.tr_entry); 488 ; 489 490 variant_part: 491 /* lambda */ 492 = $$.tr_entry = TR_NIL; 493 | 494 YCASE type_id YOF variant_list 495 = $$.tr_entry = tree5(T_TYVARPT, lineof($1.i_entry), TR_NIL, 496 $2.tr_entry, fixlist($4.tr_entry)); 497 | 498 YCASE YID ':' type_id YOF variant_list 499 = $$.tr_entry = tree5(T_TYVARPT, lineof($1.i_entry), 500 $2.tr_entry, $4.tr_entry, 501 fixlist($6.tr_entry)); 502 ; 503 variant_list: 504 variant 505 = $$.tr_entry = newlist($1.tr_entry); 506 | 507 variant_list ';' variant 508 = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry); 509 | 510 variant_list error 511 = yyPerror("Malformed record declaration", PDECL); 512 ; 513 variant: 514 /* lambda */ 515 = $$.tr_entry = TR_NIL; 516 | 517 const_list ':' '(' field_list ')' 518 = $$.tr_entry = tree4(T_TYVARNT,lineof($2.i_entry), fixlist($1.tr_entry), 519 $4.tr_entry); 520 ; 521 522 /* 523 * STATEMENT LIST 524 */ 525 526 stat_list: 527 stat 528 = $$.tr_entry = newlist($1.tr_entry); 529 | 530 stat_lsth stat 531 = { 532 if ((p = $1.tr_entry) != TR_NIL && (q = p->list_node.list)->tag == T_IFX) { 533 q->tag = T_IFEL; 534 q->if_node.else_stmnt = $2.tr_entry; 535 } else 536 $$.tr_entry= addlist($1.tr_entry, $2.tr_entry); 537 } 538 ; 539 540 stat_lsth: 541 stat_list ';' 542 = if ((q = $1.tr_entry) != TR_NIL && (p = q->list_node.list) != TR_NIL && p->tag == T_IF) { 543 if (yychar < 0) 544 yychar = yylex(); 545 if (yyshifts >= 2 && yychar == YELSE) { 546 recovered(); 547 copy((char *) (&Y), (char *) (&OY), sizeof Y); 548 yerror("Deleted ';' before keyword else"); 549 yychar = yylex(); 550 p->tag = T_IFX; 551 } 552 } 553 ; 554 555 /* 556 * CASE STATEMENT LIST 557 */ 558 559 cstat_list: 560 cstat 561 = $$.tr_entry = newlist($1.tr_entry); 562 | 563 cstat_list ';' cstat 564 = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry); 565 | 566 error 567 = { 568 $$.tr_entry = TR_NIL; 569 Kerror: 570 yyPerror("Malformed statement in case", PSTAT); 571 } 572 | 573 cstat_list error 574 = goto Kerror; 575 ; 576 577 cstat: 578 const_list ':' stat 579 = $$.tr_entry = tree4(T_CSTAT, lineof($2.i_entry), 580 fixlist($1.tr_entry), $3.tr_entry); 581 | 582 YCASELAB stat 583 = $$.tr_entry = tree4(T_CSTAT, lineof($1.i_entry), TR_NIL, 584 $2.tr_entry); 585 | 586 /* lambda */ 587 = $$.tr_entry = TR_NIL; 588 ; 589 590 /* 591 * STATEMENT 592 */ 593 594 stat: 595 /* lambda */ 596 = $$.tr_entry = TR_NIL; 597 | 598 YINT ':' stat 599 = $$.tr_entry = tree4(T_LABEL, lineof($2.i_entry), 600 $1.tr_entry == TR_NIL ? TR_NIL : 601 (struct tnode *) *hash($1.cptr, 1), $3.tr_entry); 602 | 603 proc_id 604 = $$.tr_entry = tree4(T_PCALL, lineof(yyline), $1.tr_entry, 605 TR_NIL); 606 | 607 proc_id '(' wexpr_list ')' 608 = $$.tr_entry = tree4(T_PCALL, lineof($2.i_entry), $1.tr_entry, 609 fixlist($3.tr_entry)); 610 | 611 YID error 612 = goto NSerror; 613 | 614 assign 615 | 616 YBEGIN stat_list YEND 617 = { 618 $$.tr_entry = tree3(T_BLOCK, lineof($1.i_entry), 619 fixlist($2.tr_entry)); 620 if ($3.i_entry < 0) 621 brerror($1.i_entry, "begin"); 622 } 623 | 624 YCASE expr YOF cstat_list YEND 625 = { 626 $$.tr_entry = tree4(T_CASE, lineof($1.i_entry), 627 $2.tr_entry, fixlist($4.tr_entry)); 628 if ($5.i_entry < 0) 629 brerror($1.i_entry, "case"); 630 } 631 | 632 YWITH var_list YDO stat 633 = $$.tr_entry = tree4(T_WITH, lineof($1.i_entry), 634 fixlist($2.tr_entry), $4.tr_entry); 635 | 636 YWHILE expr YDO stat 637 = $$.tr_entry = tree4(T_WHILE, lineof($1.i_entry), $2.tr_entry, 638 $4.tr_entry); 639 | 640 YREPEAT stat_list YUNTIL expr 641 = $$.tr_entry = tree4(T_REPEAT, lineof($3.i_entry), 642 fixlist($2.tr_entry), $4.tr_entry); 643 | 644 YFOR assign YTO expr YDO stat 645 = $$.tr_entry = tree5(T_FORU, lineof($1.i_entry), $2.tr_entry, 646 $4.tr_entry, $6.tr_entry); 647 | 648 YFOR assign YDOWNTO expr YDO stat 649 = $$.tr_entry = tree5(T_FORD, lineof($1.i_entry), $2.tr_entry, 650 $4.tr_entry, $6.tr_entry); 651 | 652 YGOTO YINT 653 = $$.tr_entry = tree3(T_GOTO, lineof($1.i_entry), 654 (struct tnode *) *hash($2.cptr, 1)); 655 | 656 YIF expr YTHEN stat 657 = $$.tr_entry = tree5(T_IF, lineof($1.i_entry), $2.tr_entry, 658 $4.tr_entry, TR_NIL); 659 | 660 YIF expr YTHEN stat YELSE stat 661 = $$.tr_entry = tree5(T_IFEL, lineof($1.i_entry), $2.tr_entry, 662 $4.tr_entry, $6.tr_entry); 663 | 664 error 665 = { 666 NSerror: 667 $$.tr_entry = TR_NIL; 668 yyPerror("Malformed statement", PSTAT); 669 } 670 ; 671 assign: 672 variable ':' '=' expr 673 = $$.tr_entry = tree4(T_ASGN, lineof($2.i_entry), $1.tr_entry, 674 $4.tr_entry); 675 ; 676 677 /* 678 * EXPRESSION 679 */ 680 681 expr: 682 error 683 = { 684 NEerror: 685 $$.tr_entry = TR_NIL; 686 yyPerror("Missing/malformed expression", PEXPR); 687 } 688 | 689 expr relop expr %prec '<' 690 = $$.tr_entry = tree4($2.i_entry, 691 $1.tr_entry->expr_node.const_tag == SAWCON ? 692 $3.tr_entry->expr_node.const_tag : 693 $1.tr_entry->expr_node.const_tag, 694 $1.tr_entry, $3.tr_entry); 695 | 696 '+' expr %prec UNARYSIGN 697 = $$.tr_entry = tree3(T_PLUS, $2.tr_entry->expr_node.const_tag, 698 $2.tr_entry); 699 | 700 '-' expr %prec UNARYSIGN 701 = $$.tr_entry = tree3(T_MINUS, $2.tr_entry->expr_node.const_tag, 702 $2.tr_entry); 703 | 704 expr addop expr %prec '+' 705 = $$.tr_entry = tree4($2.i_entry, 706 $1.tr_entry->expr_node.const_tag == SAWCON ? 707 $3.tr_entry->expr_node.const_tag : 708 $1.tr_entry->expr_node.const_tag, $1.tr_entry, 709 $3.tr_entry); 710 | 711 expr divop expr %prec '*' 712 = $$.tr_entry = tree4($2.i_entry, 713 $1.tr_entry->expr_node.const_tag == SAWCON ? 714 $3.tr_entry->expr_node.const_tag : 715 $1.tr_entry->expr_node.const_tag, $1.tr_entry, 716 $3.tr_entry); 717 | 718 YNIL 719 = $$.tr_entry = tree2(T_NIL, NOCON); 720 | 721 YSTRING 722 = $$.tr_entry = tree3(T_STRNG, SAWCON, $1.tr_entry); 723 | 724 YINT 725 = $$.tr_entry = tree3(T_INT, NOCON, $1.tr_entry); 726 | 727 YBINT 728 = $$.tr_entry = tree3(T_BINT, NOCON, $1.tr_entry); 729 | 730 YNUMB 731 = $$.tr_entry = tree3(T_FINT, NOCON, $1.tr_entry); 732 | 733 variable 734 | 735 YID error 736 = goto NEerror; 737 | 738 func_id '(' wexpr_list ')' 739 = $$.tr_entry = tree4(T_FCALL, NOCON, $1.tr_entry, 740 fixlist($3.tr_entry)); 741 | 742 '(' expr ')' 743 = $$.tr_entry = $2.tr_entry; 744 | 745 negop expr %prec YNOT 746 = $$.tr_entry = tree3(T_NOT, NOCON, $2.tr_entry); 747 | 748 '[' element_list ']' 749 = $$.tr_entry = tree3(T_CSET, SAWCON, fixlist($2.tr_entry)); 750 | 751 '[' ']' 752 = $$.tr_entry = tree3(T_CSET, SAWCON, TR_NIL); 753 ; 754 755 element_list: 756 element 757 = $$.tr_entry = newlist($1.tr_entry); 758 | 759 element_list ',' element 760 = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry); 761 ; 762 element: 763 expr 764 | 765 expr YDOTDOT expr 766 = $$.tr_entry = tree3(T_RANG, $1.i_entry, $3.tr_entry); 767 ; 768 769 /* 770 * QUALIFIED VARIABLES 771 */ 772 773 variable: 774 YID 775 = { 776 @@ return (identis(var, VAR)); 777 $$.tr_entry = setupvar($1.cptr, TR_NIL); 778 } 779 | 780 qual_var 781 = $1.tr_entry->var_node.qual = 782 fixlist($1.tr_entry->var_node.qual); 783 ; 784 qual_var: 785 array_id '[' expr_list ']' 786 = $$.tr_entry = setupvar($1.cptr, tree2(T_ARY, 787 (int) fixlist($3.tr_entry))); 788 | 789 qual_var '[' expr_list ']' 790 = $1.tr_entry->var_node.qual = 791 addlist($1.tr_entry->var_node.qual, 792 tree2(T_ARY, (int) fixlist($3.tr_entry))); 793 | 794 record_id '.' field_id 795 = $$.tr_entry = setupvar($1.cptr, setupfield($3.tr_entry, 796 TR_NIL)); 797 | 798 qual_var '.' field_id 799 = $1.tr_entry->var_node.qual = 800 addlist($1.tr_entry->var_node.qual, 801 setupfield($3.tr_entry, TR_NIL)); 802 | 803 ptr_id '^' 804 = $$.tr_entry = setupvar($1.cptr, tree1(T_PTR)); 805 | 806 qual_var '^' 807 = $1.tr_entry->var_node.qual = 808 addlist($1.tr_entry->var_node.qual, tree1(T_PTR)); 809 ; 810 811 /* 812 * Expression with write widths 813 */ 814 wexpr: 815 expr 816 | 817 expr ':' expr 818 = $$.tr_entry = tree4(T_WEXP, $1.i_entry, $3.tr_entry, TR_NIL); 819 | 820 expr ':' expr ':' expr 821 = $$.tr_entry = tree4(T_WEXP, $1.i_entry, $3.tr_entry, 822 $5.tr_entry); 823 | 824 expr octhex 825 = $$.tr_entry = tree4(T_WEXP, $1.i_entry, TR_NIL, $2.tr_entry); 826 | 827 expr ':' expr octhex 828 = $$.tr_entry = tree4(T_WEXP, $1.i_entry, $3.tr_entry, 829 $4.tr_entry); 830 ; 831 octhex: 832 YOCT 833 = $$.i_entry = OCT; 834 | 835 YHEX 836 = $$.i_entry = HEX; 837 ; 838 839 expr_list: 840 expr 841 = $$.tr_entry = newlist($1.tr_entry); 842 | 843 expr_list ',' expr 844 = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry); 845 ; 846 847 wexpr_list: 848 wexpr 849 = $$.tr_entry = newlist($1.tr_entry); 850 | 851 wexpr_list ',' wexpr 852 = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry); 853 ; 854 855 /* 856 * OPERATORS 857 */ 858 859 relop: 860 '=' = $$.i_entry = T_EQ; 861 | 862 '<' = $$.i_entry = T_LT; 863 | 864 '>' = $$.i_entry = T_GT; 865 | 866 '<' '>' = $$.i_entry = T_NE; 867 | 868 '<' '=' = $$.i_entry = T_LE; 869 | 870 '>' '=' = $$.i_entry = T_GE; 871 | 872 YIN = $$.i_entry = T_IN; 873 ; 874 addop: 875 '+' = $$.i_entry = T_ADD; 876 | 877 '-' = $$.i_entry = T_SUB; 878 | 879 YOR = $$.i_entry = T_OR; 880 | 881 '|' = $$.i_entry = T_OR; 882 ; 883 divop: 884 '*' = $$.i_entry = T_MULT; 885 | 886 '/' = $$.i_entry = T_DIVD; 887 | 888 YDIV = $$.i_entry = T_DIV; 889 | 890 YMOD = $$.i_entry = T_MOD; 891 | 892 YAND = $$.i_entry = T_AND; 893 | 894 '&' = $$.i_entry = T_AND; 895 ; 896 897 negop: 898 YNOT 899 | 900 '~' 901 ; 902 903 /* 904 * LISTS 905 */ 906 907 var_list: 908 variable 909 = $$.tr_entry = newlist($1.tr_entry); 910 | 911 var_list ',' variable 912 = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry); 913 ; 914 915 id_list: 916 YID 917 = $$.tr_entry = newlist($1.tr_entry); 918 | 919 id_list ',' YID 920 = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry); 921 ; 922 923 /* 924 * Identifier productions with semantic restrictions 925 * 926 * For these productions, the characters @@ signify 927 * that the associated C statement is to provide 928 * the semantic restriction for this reduction. 929 * These lines are made into a procedure yyEactr, similar to 930 * yyactr, which determines whether the corresponding reduction 931 * is permitted, or whether an error is to be signaled. 932 * A zero return from yyEactr is considered an error. 933 * YyEactr is called with an argument "var" giving the string 934 * name of the variable in question, essentially $1, although 935 * $1 will not work because yyEactr is called from loccor in 936 * the recovery routines. 937 */ 938 939 const_id: 940 YID 941 = @@ return (identis(var, CONST)); 942 ; 943 type_id: 944 YID 945 = { 946 @@ return (identis(var, TYPE)); 947 $$.tr_entry = tree3(T_TYID, lineof(yyline), $1.tr_entry); 948 } 949 ; 950 var_id: 951 YID 952 = @@ return (identis(var, VAR)); 953 ; 954 array_id: 955 YID 956 = @@ return (identis(var, ARRAY)); 957 ; 958 ptr_id: 959 YID 960 = @@ return (identis(var, PTRFILE)); 961 ; 962 record_id: 963 YID 964 = @@ return (identis(var, RECORD)); 965 ; 966 field_id: 967 YID 968 = @@ return (identis(var, FIELD)); 969 ; 970 proc_id: 971 YID 972 = @@ return (identis(var, PROC)); 973 ; 974 func_id: 975 YID 976 = @@ return (identis(var, FUNC)); 977 ; 978