1798Speter /* Copyright (c) 1979 Regents of the University of California */ 2798Speter 3798Speter /* 4798Speter * Yacc grammar for UNIX Pascal 5798Speter * 6798Speter * This grammar is processed by the commands in the shell script 7798Speter * "gram" to yield parse tables and semantic routines in the file 8798Speter * "y.tab.c" and a header defining the lexical tokens in "yy.h". 9798Speter * 10798Speter * In order for the syntactic error recovery possible with this 11798Speter * grammar to work, the grammar must be processed by a yacc which 12798Speter * has been modified to fully enumerate possibilities in states 13798Speter * which involve the symbol "error". 14798Speter * The parser used for Pascal also uses a different encoding of 15798Speter * the test entries in the action table which speeds the parse. 16798Speter * A version of yacc which will work for Pascal is included on 17798Speter * the distribution table as "eyacc". 18798Speter * 19798Speter * The "gram" script also makes the following changes to the "y.tab.c" 20798Speter * file: 21798Speter * 22798Speter * 1) Causes yyval to be declared int *. 23798Speter * 24798Speter * 2) Loads the variable yypv into a register as yyYpv so that 25798Speter * the arguments $1, ... are available as yyYpv[1] etc. 26798Speter * This produces much smaller code in the semantic actions. 27798Speter * 28798Speter * 3) Deletes the unused array yysterm. 29798Speter * 30798Speter * 4) Moves the declarations up to the flag line containing 31798Speter * '##' to the file yy.h so that the routines which use 32798Speter * these "magic numbers" don't have to all be compiled at 33798Speter * the same time. 34798Speter * 35798Speter * 5) Creates the semantic restriction checking routine yyEactr 36804Speter * by processing action lines containing `@@'. 37798Speter * 38798Speter * This compiler uses a different version of the yacc parser, a 39798Speter * different yyerror which is called yerror, and requires more 40798Speter * lookahead sets than normally provided by yacc. 41798Speter * 42798Speter * Source for the yacc used with this grammar is included on 43798Speter * distribution tapes. 44798Speter */ 45798Speter 46798Speter /* 47798Speter * TERMINAL DECLARATIONS 48798Speter * 49798Speter * Some of the terminal declarations are out of the most natural 50798Speter * alphabetic order because the error recovery 51798Speter * will guess the first of equal cost non-terminals. 52798Speter * This makes, e.g. YTO preferable to YDOWNTO. 53798Speter */ 54798Speter 55798Speter %term 56798Speter YAND YARRAY YBEGIN YCASE 57798Speter YCONST YDIV YDO YDOTDOT 58798Speter YTO YELSE YEND YFILE 59798Speter YFOR YFORWARD YFUNCTION YGOTO 60798Speter YID YIF YIN YINT 61798Speter YLABEL YMOD YNOT YNUMB 62798Speter YOF YOR YPACKED YNIL 63798Speter YPROCEDURE YPROG YRECORD YREPEAT 64798Speter YSET YSTRING YTHEN YDOWNTO 65798Speter YTYPE YUNTIL YVAR YWHILE 66798Speter YWITH YBINT YOCT YHEX 677927Smckusick YCASELAB YILLCH YEXTERN YLAST 68798Speter 69798Speter /* 70798Speter * PRECEDENCE DECLARATIONS 71798Speter * 72798Speter * Highest precedence is the unary logical NOT. 73798Speter * Next are the multiplying operators, signified by '*'. 74798Speter * Lower still are the binary adding operators, signified by '+'. 75798Speter * Finally, at lowest precedence and non-associative are the relationals. 76798Speter */ 77798Speter 78798Speter %binary '<' '=' '>' YIN 79798Speter %left '+' '-' YOR '|' 80798Speter %left UNARYSIGN 81798Speter %left '*' '/' YDIV YMOD YAND '&' 82798Speter %left YNOT 83798Speter 84798Speter %{ 85798Speter /* 86798Speter * GLOBALS FOR ACTIONS 87798Speter */ 88798Speter 89798Speter /* Copyright (c) 1979 Regents of the University of California */ 90798Speter 91*7953Speter /* static char sccsid[] = "@(#)pas.y 1.7 08/29/82"; */ 92798Speter 93798Speter /* 94798Speter * The following line marks the end of the yacc 95798Speter * Constant definitions which are removed from 96798Speter * y.tab.c and placed in the file y.tab.h. 97798Speter */ 98798Speter ## 99798Speter /* Copyright (c) 1979 Regents of the University of California */ 100798Speter 101*7953Speter static char sccsid[] = "@(#)pas.y 1.7 08/29/82"; 102798Speter 103798Speter #include "whoami.h" 104798Speter #include "0.h" 105798Speter #include "yy.h" 106798Speter #include "tree.h" 107798Speter 108798Speter #ifdef PI 109798Speter #define lineof(l) l 110798Speter #define line2of(l) l 111798Speter #endif 112798Speter 113798Speter %} 114798Speter 115798Speter %% 116798Speter 117798Speter /* 118798Speter * PRODUCTIONS 119798Speter */ 120798Speter 121798Speter goal: 122837Speter prog_hedr decls block '.' 123837Speter = funcend($1, $3, lineof($4)); 124798Speter | 125837Speter decls 126798Speter = segend(); 127798Speter ; 128798Speter 129798Speter 130798Speter prog_hedr: 131798Speter YPROG YID '(' id_list ')' ';' 132798Speter = $$ = funcbody(funchdr(tree5(T_PROG, lineof($1), $2, fixlist($4), NIL))); 133798Speter | 134*7953Speter YPROG YID ';' 135*7953Speter = $$ = funcbody(funchdr(tree5(T_PROG, lineof($1), $2, NIL, NIL))); 136*7953Speter | 137798Speter YPROG error 138798Speter = { 139798Speter yyPerror("Malformed program statement", PPROG); 140798Speter /* 141798Speter * Should make a program statement 142798Speter * with "input" and "output" here. 143798Speter */ 144798Speter $$ = funcbody(funchdr(tree5(T_PROG, lineof($1), NIL, NIL, NIL))); 145798Speter } 146798Speter ; 147798Speter block: 148798Speter YBEGIN stat_list YEND 149798Speter = { 150798Speter $$ = tree3(T_BSTL, lineof($1), fixlist($2)); 151798Speter if ($3 < 0) 152798Speter brerror($1, "begin"); 153798Speter } 154798Speter ; 155798Speter 156798Speter 157798Speter /* 158798Speter * DECLARATION PART 159798Speter */ 160798Speter decls: 161798Speter decls decl 162798Speter = trfree(); 163798Speter | 164798Speter decls error 165798Speter = { 166798Speter Derror: 167798Speter constend(), typeend(), varend(), trfree(); 168798Speter yyPerror("Malformed declaration", PDECL); 169798Speter } 170798Speter | 171798Speter /* lambda */ 172798Speter = trfree(); 173798Speter ; 174798Speter 175798Speter decl: 176798Speter labels 177798Speter | 178798Speter const_decl 179798Speter = constend(); 180798Speter | 181798Speter type_decl 182798Speter = typeend(); 183798Speter | 184798Speter var_decl 185798Speter = varend(); 186837Speter | 187837Speter proc_decl 188798Speter ; 189798Speter 190798Speter /* 191798Speter * LABEL PART 192798Speter */ 193798Speter 194798Speter labels: 195798Speter YLABEL label_decl ';' 196798Speter = label(fixlist($2), lineof($1)); 197798Speter ; 198798Speter label_decl: 199798Speter YINT 200798Speter = $$ = newlist($1 == NIL ? NIL : *hash($1, 1)); 201798Speter | 202798Speter label_decl ',' YINT 203798Speter = $$ = addlist($1, $3 == NIL ? NIL : *hash($3, 1)); 204798Speter ; 205798Speter 206798Speter /* 207798Speter * CONST PART 208798Speter */ 209798Speter 210798Speter const_decl: 211798Speter YCONST YID '=' const ';' 212798Speter = constbeg($1, line2of($2)), const(lineof($3), $2, $4); 213798Speter | 214798Speter const_decl YID '=' const ';' 215798Speter = const(lineof($3), $2, $4); 216798Speter | 217798Speter YCONST error 218798Speter = { 219798Speter constbeg($1, line2of($1)); 220798Speter Cerror: 221798Speter yyPerror("Malformed const declaration", PDECL); 222798Speter } 223798Speter | 224798Speter const_decl error 225798Speter = goto Cerror; 226798Speter ; 227798Speter 228798Speter /* 229798Speter * TYPE PART 230798Speter */ 231798Speter 232798Speter type_decl: 233798Speter YTYPE YID '=' type ';' 234798Speter = typebeg($1, line2of($2)), type(lineof($3), $2, $4); 235798Speter | 236798Speter type_decl YID '=' type ';' 237798Speter = type(lineof($3), $2, $4); 238798Speter | 239798Speter YTYPE error 240798Speter = { 241798Speter typebeg($1, line2of($1)); 242798Speter Terror: 243798Speter yyPerror("Malformed type declaration", PDECL); 244798Speter } 245798Speter | 246798Speter type_decl error 247798Speter = goto Terror; 248798Speter ; 249798Speter 250798Speter /* 251798Speter * VAR PART 252798Speter */ 253798Speter 254798Speter var_decl: 255798Speter YVAR id_list ':' type ';' 256798Speter = varbeg($1, line2of($3)), var(lineof($3), fixlist($2), $4); 257798Speter | 258798Speter var_decl id_list ':' type ';' 259798Speter = var(lineof($3), fixlist($2), $4); 260798Speter | 261798Speter YVAR error 262798Speter = { 263798Speter varbeg($1, line2of($1)); 264798Speter Verror: 265798Speter yyPerror("Malformed var declaration", PDECL); 266798Speter } 267798Speter | 268798Speter var_decl error 269798Speter = goto Verror; 270798Speter ; 271798Speter 272798Speter /* 273798Speter * PROCEDURE AND FUNCTION DECLARATION PART 274798Speter */ 275798Speter 276837Speter proc_decl: 277798Speter phead YFORWARD ';' 278798Speter = funcfwd($1); 279798Speter | 280798Speter phead YEXTERN ';' 281798Speter = funcext($1); 282798Speter | 283837Speter pheadres decls block ';' 284837Speter = funcend($1, $3, lineof($4)); 285798Speter ; 286798Speter pheadres: 287798Speter phead 288798Speter = funcbody($1); 289798Speter ; 290798Speter phead: 291798Speter porf YID params ftype ';' 292798Speter = $$ = funchdr(tree5($1, lineof($5), $2, $3, $4)); 293798Speter ; 294798Speter porf: 295798Speter YPROCEDURE 296798Speter = $$ = T_PDEC; 297798Speter | 298798Speter YFUNCTION 299798Speter = $$ = T_FDEC; 300798Speter ; 301798Speter params: 302798Speter '(' param_list ')' 303798Speter = $$ = fixlist($2); 304798Speter | 305798Speter /* lambda */ 306798Speter = $$ = NIL; 307798Speter ; 308798Speter 309798Speter /* 310798Speter * PARAMETERS 311798Speter */ 312798Speter 313798Speter param: 314798Speter id_list ':' type 315798Speter = $$ = tree3(T_PVAL, fixlist($1), $3); 316798Speter | 317798Speter YVAR id_list ':' type 318798Speter = $$ = tree3(T_PVAR, fixlist($2), $4); 319798Speter | 3203298Smckusic YFUNCTION id_list params ftype 3213298Smckusic = $$ = tree5(T_PFUNC, fixlist($2), $4, $3, lineof($1)); 322798Speter | 3233298Smckusic YPROCEDURE id_list params ftype 3243298Smckusic = $$ = tree5(T_PPROC, fixlist($2), $4, $3, lineof($1)); 325798Speter ; 326798Speter ftype: 327798Speter ':' type 328798Speter = $$ = $2; 329798Speter | 330798Speter /* lambda */ 331798Speter = $$ = NIL; 332798Speter ; 333798Speter param_list: 334798Speter param 335798Speter = $$ = newlist($1); 336798Speter | 337798Speter param_list ';' param 338798Speter = $$ = addlist($1, $3); 339798Speter ; 340798Speter 341798Speter /* 342798Speter * CONSTANTS 343798Speter */ 344798Speter 345798Speter const: 346798Speter YSTRING 347798Speter = $$ = tree2(T_CSTRNG, $1); 348798Speter | 349798Speter number 350798Speter | 351798Speter '+' number 352798Speter = $$ = tree2(T_PLUSC, $2); 353798Speter | 354798Speter '-' number 355798Speter = $$ = tree2(T_MINUSC, $2); 356798Speter ; 357798Speter number: 358798Speter const_id 359798Speter = $$ = tree2(T_ID, $1); 360798Speter | 361798Speter YINT 362798Speter = $$ = tree2(T_CINT, $1); 363798Speter | 364798Speter YBINT 365798Speter = $$ = tree2(T_CBINT, $1); 366798Speter | 367798Speter YNUMB 368798Speter = $$ = tree2(T_CFINT, $1); 369798Speter ; 370798Speter const_list: 371798Speter const 372798Speter = $$ = newlist($1); 373798Speter | 374798Speter const_list ',' const 375798Speter = $$ = addlist($1, $3); 376798Speter ; 377798Speter 378798Speter /* 379798Speter * TYPES 380798Speter */ 381798Speter 382798Speter type: 383798Speter simple_type 384798Speter | 385798Speter '^' YID 386798Speter = $$ = tree3(T_TYPTR, lineof($1), tree2(T_ID, $2)); 387798Speter | 388798Speter struct_type 389798Speter | 390798Speter YPACKED struct_type 391798Speter = $$ = tree3(T_TYPACK, lineof($1), $2); 392798Speter ; 393798Speter simple_type: 394798Speter type_id 395798Speter | 396798Speter '(' id_list ')' 397798Speter = $$ = tree3(T_TYSCAL, lineof($1), fixlist($2)); 398798Speter | 399798Speter const YDOTDOT const 400798Speter = $$ = tree4(T_TYRANG, lineof($2), $1, $3); 401798Speter ; 402798Speter struct_type: 403798Speter YARRAY '[' simple_type_list ']' YOF type 404798Speter = $$ = tree4(T_TYARY, lineof($1), fixlist($3), $6); 405798Speter | 406798Speter YFILE YOF type 407798Speter = $$ = tree3(T_TYFILE, lineof($1), $3); 408798Speter | 409798Speter YSET YOF simple_type 410798Speter = $$ = tree3(T_TYSET, lineof($1), $3); 411798Speter | 412798Speter YRECORD field_list YEND 413798Speter = { 414798Speter $$ = setuptyrec( lineof( $1 ) , $2 ); 415798Speter if ($3 < 0) 416798Speter brerror($1, "record"); 417798Speter } 418798Speter ; 419798Speter simple_type_list: 420798Speter simple_type 421798Speter = $$ = newlist($1); 422798Speter | 423798Speter simple_type_list ',' simple_type 424798Speter = $$ = addlist($1, $3); 425798Speter ; 426798Speter 427798Speter /* 428798Speter * RECORD TYPE 429798Speter */ 430798Speter field_list: 431798Speter fixed_part variant_part 432798Speter = $$ = tree4(T_FLDLST, lineof(NIL), fixlist($1), $2); 433798Speter ; 434798Speter fixed_part: 435798Speter field 436798Speter = $$ = newlist($1); 437798Speter | 438798Speter fixed_part ';' field 439798Speter = $$ = addlist($1, $3); 440798Speter | 441798Speter fixed_part error 442798Speter = yyPerror("Malformed record declaration", PDECL); 443798Speter ; 444798Speter field: 445798Speter /* lambda */ 446798Speter = $$ = NIL; 447798Speter | 448798Speter id_list ':' type 449798Speter = $$ = tree4(T_RFIELD, lineof($2), fixlist($1), $3); 450798Speter ; 451798Speter 452798Speter variant_part: 453798Speter /* lambda */ 454798Speter = $$ = NIL; 455798Speter | 456798Speter YCASE type_id YOF variant_list 457798Speter = $$ = tree5(T_TYVARPT, lineof($1), NIL, $2, fixlist($4)); 458798Speter | 459798Speter YCASE YID ':' type_id YOF variant_list 460798Speter = $$ = tree5(T_TYVARPT, lineof($1), $2, $4, fixlist($6)); 461798Speter ; 462798Speter variant_list: 463798Speter variant 464798Speter = $$ = newlist($1); 465798Speter | 466798Speter variant_list ';' variant 467798Speter = $$ = addlist($1, $3); 468798Speter | 469798Speter variant_list error 470798Speter = yyPerror("Malformed record declaration", PDECL); 471798Speter ; 472798Speter variant: 473798Speter /* lambda */ 474798Speter = $$ = NIL; 475798Speter | 476798Speter const_list ':' '(' field_list ')' 477798Speter = $$ = tree4(T_TYVARNT, lineof($2), fixlist($1), $4); 478798Speter | 479798Speter const_list ':' '(' ')' 480798Speter = $$ = tree4(T_TYVARNT, lineof($2), fixlist($1), NIL); 481798Speter ; 482798Speter 483798Speter /* 484798Speter * STATEMENT LIST 485798Speter */ 486798Speter 487798Speter stat_list: 488798Speter stat 489798Speter = $$ = newlist($1); 490798Speter | 491798Speter stat_lsth stat 492798Speter = { 493798Speter if ((p = $1) != NIL && (q = p[1])[0] == T_IFX) { 494798Speter q[0] = T_IFEL; 495798Speter q[4] = $2; 496798Speter } else 497798Speter $$ = addlist($1, $2); 498798Speter } 499798Speter ; 500798Speter 501798Speter stat_lsth: 502798Speter stat_list ';' 503798Speter = if ((q = $1) != NIL && (p = q[1]) != NIL && p[0] == T_IF) { 504798Speter if (yychar < 0) 505798Speter yychar = yylex(); 506798Speter if (yyshifts >= 2 && yychar == YELSE) { 507798Speter recovered(); 508798Speter copy(&Y, &OY, sizeof Y); 509798Speter yerror("Deleted ';' before keyword else"); 510798Speter yychar = yylex(); 511798Speter p[0] = T_IFX; 512798Speter } 513798Speter } 514798Speter ; 515798Speter 516798Speter /* 517798Speter * CASE STATEMENT LIST 518798Speter */ 519798Speter 520798Speter cstat_list: 521798Speter cstat 522798Speter = $$ = newlist($1); 523798Speter | 524798Speter cstat_list ';' cstat 525798Speter = $$ = addlist($1, $3); 526798Speter | 527798Speter error 528798Speter = { 529798Speter $$ = NIL; 530798Speter Kerror: 531798Speter yyPerror("Malformed statement in case", PSTAT); 532798Speter } 533798Speter | 534798Speter cstat_list error 535798Speter = goto Kerror; 536798Speter ; 537798Speter 538798Speter cstat: 539798Speter const_list ':' stat 540798Speter = $$ = tree4(T_CSTAT, lineof($2), fixlist($1), $3); 541798Speter | 542798Speter YCASELAB stat 543798Speter = $$ = tree4(T_CSTAT, lineof($1), NIL, $2); 544798Speter | 545798Speter /* lambda */ 546798Speter = $$ = NIL; 547798Speter ; 548798Speter 549798Speter /* 550798Speter * STATEMENT 551798Speter */ 552798Speter 553798Speter stat: 554798Speter /* lambda */ 555798Speter = $$ = NIL; 556798Speter | 557798Speter YINT ':' stat 558798Speter = $$ = tree4(T_LABEL, lineof($2), $1 == NIL ? NIL : *hash($1, 1), $3); 559798Speter | 560798Speter proc_id 561798Speter = $$ = tree4(T_PCALL, lineof(yyline), $1, NIL); 562798Speter | 563798Speter proc_id '(' wexpr_list ')' 564798Speter = $$ = tree4(T_PCALL, lineof($2), $1, fixlist($3)); 565798Speter | 566798Speter YID error 567798Speter = goto NSerror; 568798Speter | 569798Speter assign 570798Speter | 571798Speter YBEGIN stat_list YEND 572798Speter = { 573798Speter $$ = tree3(T_BLOCK, lineof($1), fixlist($2)); 574798Speter if ($3 < 0) 575798Speter brerror($1, "begin"); 576798Speter } 577798Speter | 578798Speter YCASE expr YOF cstat_list YEND 579798Speter = { 580798Speter $$ = tree4(T_CASE, lineof($1), $2, fixlist($4)); 581798Speter if ($5 < 0) 582798Speter brerror($1, "case"); 583798Speter } 584798Speter | 585798Speter YWITH var_list YDO stat 586798Speter = $$ = tree4(T_WITH, lineof($1), fixlist($2), $4); 587798Speter | 588798Speter YWHILE expr YDO stat 589798Speter = $$ = tree4(T_WHILE, lineof($1), $2, $4); 590798Speter | 591798Speter YREPEAT stat_list YUNTIL expr 592798Speter = $$ = tree4(T_REPEAT, lineof($3), fixlist($2), $4); 593798Speter | 594798Speter YFOR assign YTO expr YDO stat 595798Speter = $$ = tree5(T_FORU, lineof($1), $2, $4, $6); 596798Speter | 597798Speter YFOR assign YDOWNTO expr YDO stat 598798Speter = $$ = tree5(T_FORD, lineof($1), $2, $4, $6); 599798Speter | 600798Speter YGOTO YINT 601798Speter = $$ = tree3(T_GOTO, lineof($1), *hash($2, 1)); 602798Speter | 603798Speter YIF expr YTHEN stat 604798Speter = $$ = tree5(T_IF, lineof($1), $2, $4, NIL); 605798Speter | 606798Speter YIF expr YTHEN stat YELSE stat 607798Speter = $$ = tree5(T_IFEL, lineof($1), $2, $4, $6); 608798Speter | 609798Speter error 610798Speter = { 611798Speter NSerror: 612798Speter $$ = NIL; 613798Speter Serror: 614798Speter yyPerror("Malformed statement", PSTAT); 615798Speter } 616798Speter ; 617798Speter assign: 618798Speter variable ':' '=' expr 619798Speter = $$ = tree4(T_ASGN, lineof($2), $1, $4); 620798Speter ; 621798Speter 622798Speter /* 623798Speter * EXPRESSION 624798Speter */ 625798Speter 626798Speter expr: 627798Speter error 628798Speter = { 629798Speter NEerror: 630798Speter $$ = NIL; 631798Speter Eerror: 632798Speter yyPerror("Missing/malformed expression", PEXPR); 633798Speter } 634798Speter | 635798Speter expr relop expr %prec '<' 636798Speter = $$ = tree4($2, $1[1] == SAWCON ? $3[1] : $1[1], $1, $3); 637798Speter | 638798Speter '+' expr %prec UNARYSIGN 639798Speter = $$ = tree3(T_PLUS, $2[1], $2); 640798Speter | 641798Speter '-' expr %prec UNARYSIGN 642798Speter = $$ = tree3(T_MINUS, $2[1], $2); 643798Speter | 644798Speter expr addop expr %prec '+' 645798Speter = $$ = tree4($2, $1[1] == SAWCON ? $3[1] : $1[1], $1, $3); 646798Speter | 647798Speter expr divop expr %prec '*' 648798Speter = $$ = tree4($2, $1[1] == SAWCON ? $3[1] : $1[1], $1, $3); 649798Speter | 650798Speter YNIL 651798Speter = $$ = tree2(T_NIL, NOCON); 652798Speter | 653798Speter YSTRING 654798Speter = $$ = tree3(T_STRNG, SAWCON, $1); 655798Speter | 656798Speter YINT 657798Speter = $$ = tree3(T_INT, NOCON, $1); 658798Speter | 659798Speter YBINT 660798Speter = $$ = tree3(T_BINT, NOCON, $1); 661798Speter | 662798Speter YNUMB 663798Speter = $$ = tree3(T_FINT, NOCON, $1); 664798Speter | 665798Speter variable 666798Speter | 667798Speter YID error 668798Speter = goto NEerror; 669798Speter | 670798Speter func_id '(' wexpr_list ')' 671798Speter = $$ = tree4(T_FCALL, NOCON, $1, fixlist($3)); 672798Speter | 673798Speter '(' expr ')' 674798Speter = $$ = $2; 675798Speter | 676798Speter negop expr %prec YNOT 677798Speter = $$ = tree3(T_NOT, NOCON, $2); 678798Speter | 679798Speter '[' element_list ']' 680798Speter = $$ = tree3(T_CSET, SAWCON, fixlist($2)); 681798Speter | 682798Speter '[' ']' 683798Speter = $$ = tree3(T_CSET, SAWCON, NIL); 684798Speter ; 685798Speter 686798Speter element_list: 687798Speter element 688798Speter = $$ = newlist($1); 689798Speter | 690798Speter element_list ',' element 691798Speter = $$ = addlist($1, $3); 692798Speter ; 693798Speter element: 694798Speter expr 695798Speter | 696798Speter expr YDOTDOT expr 697798Speter = $$ = tree3(T_RANG, $1, $3); 698798Speter ; 699798Speter 700798Speter /* 701798Speter * QUALIFIED VARIABLES 702798Speter */ 703798Speter 704798Speter variable: 705798Speter YID 706798Speter = { 707804Speter @@ return (identis(var, VAR)); 708798Speter $$ = setupvar($1, NIL); 709798Speter } 710798Speter | 711798Speter qual_var 712798Speter = $1[3] = fixlist($1[3]); 713798Speter ; 714798Speter qual_var: 715798Speter array_id '[' expr_list ']' 716798Speter = $$ = setupvar($1, tree2(T_ARY, fixlist($3))); 717798Speter | 718798Speter qual_var '[' expr_list ']' 719798Speter = $1[3] = addlist($1[3], tree2(T_ARY, fixlist($3))); 720798Speter | 721798Speter record_id '.' field_id 722798Speter = $$ = setupvar($1, setupfield($3, NIL)); 723798Speter | 724798Speter qual_var '.' field_id 725798Speter = $1[3] = addlist($1[3], setupfield($3, NIL)); 726798Speter | 727798Speter ptr_id '^' 728798Speter = $$ = setupvar($1, tree1(T_PTR)); 729798Speter | 730798Speter qual_var '^' 731798Speter = $1[3] = addlist($1[3], tree1(T_PTR)); 732798Speter ; 733798Speter 734798Speter /* 735798Speter * Expression with write widths 736798Speter */ 737798Speter wexpr: 738798Speter expr 739798Speter | 740798Speter expr ':' expr 741798Speter = $$ = tree4(T_WEXP, $1, $3, NIL); 742798Speter | 743798Speter expr ':' expr ':' expr 744798Speter = $$ = tree4(T_WEXP, $1, $3, $5); 745798Speter | 746798Speter expr octhex 747798Speter = $$ = tree4(T_WEXP, $1, NIL, $2); 748798Speter | 749798Speter expr ':' expr octhex 750798Speter = $$ = tree4(T_WEXP, $1, $3, $4); 751798Speter ; 752798Speter octhex: 753798Speter YOCT 754798Speter = $$ = OCT; 755798Speter | 756798Speter YHEX 757798Speter = $$ = HEX; 758798Speter ; 759798Speter 760798Speter expr_list: 761798Speter expr 762798Speter = $$ = newlist($1); 763798Speter | 764798Speter expr_list ',' expr 765798Speter = $$ = addlist($1, $3); 766798Speter ; 767798Speter 768798Speter wexpr_list: 769798Speter wexpr 770798Speter = $$ = newlist($1); 771798Speter | 772798Speter wexpr_list ',' wexpr 773798Speter = $$ = addlist($1, $3); 774798Speter ; 775798Speter 776798Speter /* 777798Speter * OPERATORS 778798Speter */ 779798Speter 780798Speter relop: 781798Speter '=' = $$ = T_EQ; 782798Speter | 783798Speter '<' = $$ = T_LT; 784798Speter | 785798Speter '>' = $$ = T_GT; 786798Speter | 787798Speter '<' '>' = $$ = T_NE; 788798Speter | 789798Speter '<' '=' = $$ = T_LE; 790798Speter | 791798Speter '>' '=' = $$ = T_GE; 792798Speter | 793798Speter YIN = $$ = T_IN; 794798Speter ; 795798Speter addop: 796798Speter '+' = $$ = T_ADD; 797798Speter | 798798Speter '-' = $$ = T_SUB; 799798Speter | 800798Speter YOR = $$ = T_OR; 801798Speter | 802798Speter '|' = $$ = T_OR; 803798Speter ; 804798Speter divop: 805798Speter '*' = $$ = T_MULT; 806798Speter | 807798Speter '/' = $$ = T_DIVD; 808798Speter | 809798Speter YDIV = $$ = T_DIV; 810798Speter | 811798Speter YMOD = $$ = T_MOD; 812798Speter | 813798Speter YAND = $$ = T_AND; 814798Speter | 815798Speter '&' = $$ = T_AND; 816798Speter ; 817798Speter 818798Speter negop: 819798Speter YNOT 820798Speter | 821798Speter '~' 822798Speter ; 823798Speter 824798Speter /* 825798Speter * LISTS 826798Speter */ 827798Speter 828798Speter var_list: 829798Speter variable 830798Speter = $$ = newlist($1); 831798Speter | 832798Speter var_list ',' variable 833798Speter = $$ = addlist($1, $3); 834798Speter ; 835798Speter 836798Speter id_list: 837798Speter YID 838798Speter = $$ = newlist($1); 839798Speter | 840798Speter id_list ',' YID 841798Speter = $$ = addlist($1, $3); 842798Speter ; 843798Speter 844798Speter /* 845798Speter * Identifier productions with semantic restrictions 846798Speter * 847804Speter * For these productions, the characters @@ signify 848798Speter * that the associated C statement is to provide 849798Speter * the semantic restriction for this reduction. 850798Speter * These lines are made into a procedure yyEactr, similar to 851798Speter * yyactr, which determines whether the corresponding reduction 852798Speter * is permitted, or whether an error is to be signaled. 853798Speter * A zero return from yyEactr is considered an error. 854798Speter * YyEactr is called with an argument "var" giving the string 855798Speter * name of the variable in question, essentially $1, although 856798Speter * $1 will not work because yyEactr is called from loccor in 857798Speter * the recovery routines. 858798Speter */ 859798Speter 860798Speter const_id: 861798Speter YID 862804Speter = @@ return (identis(var, CONST)); 863798Speter ; 864798Speter type_id: 865798Speter YID 866798Speter = { 867804Speter @@ return (identis(var, TYPE)); 868798Speter $$ = tree3(T_TYID, lineof(yyline), $1); 869798Speter } 870798Speter ; 871798Speter var_id: 872798Speter YID 873804Speter = @@ return (identis(var, VAR)); 874798Speter ; 875798Speter array_id: 876798Speter YID 877804Speter = @@ return (identis(var, ARRAY)); 878798Speter ; 879798Speter ptr_id: 880798Speter YID 881804Speter = @@ return (identis(var, PTRFILE)); 882798Speter ; 883798Speter record_id: 884798Speter YID 885804Speter = @@ return (identis(var, RECORD)); 886798Speter ; 887798Speter field_id: 888798Speter YID 889804Speter = @@ return (identis(var, FIELD)); 890798Speter ; 891798Speter proc_id: 892798Speter YID 893804Speter = @@ return (identis(var, PROC)); 894798Speter ; 895798Speter func_id: 896798Speter YID 897804Speter = @@ return (identis(var, FUNC)); 898798Speter ; 899