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 67*7927Smckusick 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*7927Smckusick /* static char sccsid[] = "@(#)pas.y 1.6 08/27/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*7927Smckusick static char sccsid[] = "@(#)pas.y 1.6 08/27/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 | 134798Speter YPROG error 135798Speter = { 136798Speter yyPerror("Malformed program statement", PPROG); 137798Speter /* 138798Speter * Should make a program statement 139798Speter * with "input" and "output" here. 140798Speter */ 141798Speter $$ = funcbody(funchdr(tree5(T_PROG, lineof($1), NIL, NIL, NIL))); 142798Speter } 143798Speter ; 144798Speter block: 145798Speter YBEGIN stat_list YEND 146798Speter = { 147798Speter $$ = tree3(T_BSTL, lineof($1), fixlist($2)); 148798Speter if ($3 < 0) 149798Speter brerror($1, "begin"); 150798Speter } 151798Speter ; 152798Speter 153798Speter 154798Speter /* 155798Speter * DECLARATION PART 156798Speter */ 157798Speter decls: 158798Speter decls decl 159798Speter = trfree(); 160798Speter | 161798Speter decls error 162798Speter = { 163798Speter Derror: 164798Speter constend(), typeend(), varend(), trfree(); 165798Speter yyPerror("Malformed declaration", PDECL); 166798Speter } 167798Speter | 168798Speter /* lambda */ 169798Speter = trfree(); 170798Speter ; 171798Speter 172798Speter decl: 173798Speter labels 174798Speter | 175798Speter const_decl 176798Speter = constend(); 177798Speter | 178798Speter type_decl 179798Speter = typeend(); 180798Speter | 181798Speter var_decl 182798Speter = varend(); 183837Speter | 184837Speter proc_decl 185798Speter ; 186798Speter 187798Speter /* 188798Speter * LABEL PART 189798Speter */ 190798Speter 191798Speter labels: 192798Speter YLABEL label_decl ';' 193798Speter = label(fixlist($2), lineof($1)); 194798Speter ; 195798Speter label_decl: 196798Speter YINT 197798Speter = $$ = newlist($1 == NIL ? NIL : *hash($1, 1)); 198798Speter | 199798Speter label_decl ',' YINT 200798Speter = $$ = addlist($1, $3 == NIL ? NIL : *hash($3, 1)); 201798Speter ; 202798Speter 203798Speter /* 204798Speter * CONST PART 205798Speter */ 206798Speter 207798Speter const_decl: 208798Speter YCONST YID '=' const ';' 209798Speter = constbeg($1, line2of($2)), const(lineof($3), $2, $4); 210798Speter | 211798Speter const_decl YID '=' const ';' 212798Speter = const(lineof($3), $2, $4); 213798Speter | 214798Speter YCONST error 215798Speter = { 216798Speter constbeg($1, line2of($1)); 217798Speter Cerror: 218798Speter yyPerror("Malformed const declaration", PDECL); 219798Speter } 220798Speter | 221798Speter const_decl error 222798Speter = goto Cerror; 223798Speter ; 224798Speter 225798Speter /* 226798Speter * TYPE PART 227798Speter */ 228798Speter 229798Speter type_decl: 230798Speter YTYPE YID '=' type ';' 231798Speter = typebeg($1, line2of($2)), type(lineof($3), $2, $4); 232798Speter | 233798Speter type_decl YID '=' type ';' 234798Speter = type(lineof($3), $2, $4); 235798Speter | 236798Speter YTYPE error 237798Speter = { 238798Speter typebeg($1, line2of($1)); 239798Speter Terror: 240798Speter yyPerror("Malformed type declaration", PDECL); 241798Speter } 242798Speter | 243798Speter type_decl error 244798Speter = goto Terror; 245798Speter ; 246798Speter 247798Speter /* 248798Speter * VAR PART 249798Speter */ 250798Speter 251798Speter var_decl: 252798Speter YVAR id_list ':' type ';' 253798Speter = varbeg($1, line2of($3)), var(lineof($3), fixlist($2), $4); 254798Speter | 255798Speter var_decl id_list ':' type ';' 256798Speter = var(lineof($3), fixlist($2), $4); 257798Speter | 258798Speter YVAR error 259798Speter = { 260798Speter varbeg($1, line2of($1)); 261798Speter Verror: 262798Speter yyPerror("Malformed var declaration", PDECL); 263798Speter } 264798Speter | 265798Speter var_decl error 266798Speter = goto Verror; 267798Speter ; 268798Speter 269798Speter /* 270798Speter * PROCEDURE AND FUNCTION DECLARATION PART 271798Speter */ 272798Speter 273837Speter proc_decl: 274798Speter phead YFORWARD ';' 275798Speter = funcfwd($1); 276798Speter | 277798Speter phead YEXTERN ';' 278798Speter = funcext($1); 279798Speter | 280837Speter pheadres decls block ';' 281837Speter = funcend($1, $3, lineof($4)); 282798Speter ; 283798Speter pheadres: 284798Speter phead 285798Speter = funcbody($1); 286798Speter ; 287798Speter phead: 288798Speter porf YID params ftype ';' 289798Speter = $$ = funchdr(tree5($1, lineof($5), $2, $3, $4)); 290798Speter ; 291798Speter porf: 292798Speter YPROCEDURE 293798Speter = $$ = T_PDEC; 294798Speter | 295798Speter YFUNCTION 296798Speter = $$ = T_FDEC; 297798Speter ; 298798Speter params: 299798Speter '(' param_list ')' 300798Speter = $$ = fixlist($2); 301798Speter | 302798Speter /* lambda */ 303798Speter = $$ = NIL; 304798Speter ; 305798Speter 306798Speter /* 307798Speter * PARAMETERS 308798Speter */ 309798Speter 310798Speter param: 311798Speter id_list ':' type 312798Speter = $$ = tree3(T_PVAL, fixlist($1), $3); 313798Speter | 314798Speter YVAR id_list ':' type 315798Speter = $$ = tree3(T_PVAR, fixlist($2), $4); 316798Speter | 3173298Smckusic YFUNCTION id_list params ftype 3183298Smckusic = $$ = tree5(T_PFUNC, fixlist($2), $4, $3, lineof($1)); 319798Speter | 3203298Smckusic YPROCEDURE id_list params ftype 3213298Smckusic = $$ = tree5(T_PPROC, fixlist($2), $4, $3, lineof($1)); 322798Speter ; 323798Speter ftype: 324798Speter ':' type 325798Speter = $$ = $2; 326798Speter | 327798Speter /* lambda */ 328798Speter = $$ = NIL; 329798Speter ; 330798Speter param_list: 331798Speter param 332798Speter = $$ = newlist($1); 333798Speter | 334798Speter param_list ';' param 335798Speter = $$ = addlist($1, $3); 336798Speter ; 337798Speter 338798Speter /* 339798Speter * CONSTANTS 340798Speter */ 341798Speter 342798Speter const: 343798Speter YSTRING 344798Speter = $$ = tree2(T_CSTRNG, $1); 345798Speter | 346798Speter number 347798Speter | 348798Speter '+' number 349798Speter = $$ = tree2(T_PLUSC, $2); 350798Speter | 351798Speter '-' number 352798Speter = $$ = tree2(T_MINUSC, $2); 353798Speter ; 354798Speter number: 355798Speter const_id 356798Speter = $$ = tree2(T_ID, $1); 357798Speter | 358798Speter YINT 359798Speter = $$ = tree2(T_CINT, $1); 360798Speter | 361798Speter YBINT 362798Speter = $$ = tree2(T_CBINT, $1); 363798Speter | 364798Speter YNUMB 365798Speter = $$ = tree2(T_CFINT, $1); 366798Speter ; 367798Speter const_list: 368798Speter const 369798Speter = $$ = newlist($1); 370798Speter | 371798Speter const_list ',' const 372798Speter = $$ = addlist($1, $3); 373798Speter ; 374798Speter 375798Speter /* 376798Speter * TYPES 377798Speter */ 378798Speter 379798Speter type: 380798Speter simple_type 381798Speter | 382798Speter '^' YID 383798Speter = $$ = tree3(T_TYPTR, lineof($1), tree2(T_ID, $2)); 384798Speter | 385798Speter struct_type 386798Speter | 387798Speter YPACKED struct_type 388798Speter = $$ = tree3(T_TYPACK, lineof($1), $2); 389798Speter ; 390798Speter simple_type: 391798Speter type_id 392798Speter | 393798Speter '(' id_list ')' 394798Speter = $$ = tree3(T_TYSCAL, lineof($1), fixlist($2)); 395798Speter | 396798Speter const YDOTDOT const 397798Speter = $$ = tree4(T_TYRANG, lineof($2), $1, $3); 398798Speter ; 399798Speter struct_type: 400798Speter YARRAY '[' simple_type_list ']' YOF type 401798Speter = $$ = tree4(T_TYARY, lineof($1), fixlist($3), $6); 402798Speter | 403798Speter YFILE YOF type 404798Speter = $$ = tree3(T_TYFILE, lineof($1), $3); 405798Speter | 406798Speter YSET YOF simple_type 407798Speter = $$ = tree3(T_TYSET, lineof($1), $3); 408798Speter | 409798Speter YRECORD field_list YEND 410798Speter = { 411798Speter $$ = setuptyrec( lineof( $1 ) , $2 ); 412798Speter if ($3 < 0) 413798Speter brerror($1, "record"); 414798Speter } 415798Speter ; 416798Speter simple_type_list: 417798Speter simple_type 418798Speter = $$ = newlist($1); 419798Speter | 420798Speter simple_type_list ',' simple_type 421798Speter = $$ = addlist($1, $3); 422798Speter ; 423798Speter 424798Speter /* 425798Speter * RECORD TYPE 426798Speter */ 427798Speter field_list: 428798Speter fixed_part variant_part 429798Speter = $$ = tree4(T_FLDLST, lineof(NIL), fixlist($1), $2); 430798Speter ; 431798Speter fixed_part: 432798Speter field 433798Speter = $$ = newlist($1); 434798Speter | 435798Speter fixed_part ';' field 436798Speter = $$ = addlist($1, $3); 437798Speter | 438798Speter fixed_part error 439798Speter = yyPerror("Malformed record declaration", PDECL); 440798Speter ; 441798Speter field: 442798Speter /* lambda */ 443798Speter = $$ = NIL; 444798Speter | 445798Speter id_list ':' type 446798Speter = $$ = tree4(T_RFIELD, lineof($2), fixlist($1), $3); 447798Speter ; 448798Speter 449798Speter variant_part: 450798Speter /* lambda */ 451798Speter = $$ = NIL; 452798Speter | 453798Speter YCASE type_id YOF variant_list 454798Speter = $$ = tree5(T_TYVARPT, lineof($1), NIL, $2, fixlist($4)); 455798Speter | 456798Speter YCASE YID ':' type_id YOF variant_list 457798Speter = $$ = tree5(T_TYVARPT, lineof($1), $2, $4, fixlist($6)); 458798Speter ; 459798Speter variant_list: 460798Speter variant 461798Speter = $$ = newlist($1); 462798Speter | 463798Speter variant_list ';' variant 464798Speter = $$ = addlist($1, $3); 465798Speter | 466798Speter variant_list error 467798Speter = yyPerror("Malformed record declaration", PDECL); 468798Speter ; 469798Speter variant: 470798Speter /* lambda */ 471798Speter = $$ = NIL; 472798Speter | 473798Speter const_list ':' '(' field_list ')' 474798Speter = $$ = tree4(T_TYVARNT, lineof($2), fixlist($1), $4); 475798Speter | 476798Speter const_list ':' '(' ')' 477798Speter = $$ = tree4(T_TYVARNT, lineof($2), fixlist($1), NIL); 478798Speter ; 479798Speter 480798Speter /* 481798Speter * STATEMENT LIST 482798Speter */ 483798Speter 484798Speter stat_list: 485798Speter stat 486798Speter = $$ = newlist($1); 487798Speter | 488798Speter stat_lsth stat 489798Speter = { 490798Speter if ((p = $1) != NIL && (q = p[1])[0] == T_IFX) { 491798Speter q[0] = T_IFEL; 492798Speter q[4] = $2; 493798Speter } else 494798Speter $$ = addlist($1, $2); 495798Speter } 496798Speter ; 497798Speter 498798Speter stat_lsth: 499798Speter stat_list ';' 500798Speter = if ((q = $1) != NIL && (p = q[1]) != NIL && p[0] == T_IF) { 501798Speter if (yychar < 0) 502798Speter yychar = yylex(); 503798Speter if (yyshifts >= 2 && yychar == YELSE) { 504798Speter recovered(); 505798Speter copy(&Y, &OY, sizeof Y); 506798Speter yerror("Deleted ';' before keyword else"); 507798Speter yychar = yylex(); 508798Speter p[0] = T_IFX; 509798Speter } 510798Speter } 511798Speter ; 512798Speter 513798Speter /* 514798Speter * CASE STATEMENT LIST 515798Speter */ 516798Speter 517798Speter cstat_list: 518798Speter cstat 519798Speter = $$ = newlist($1); 520798Speter | 521798Speter cstat_list ';' cstat 522798Speter = $$ = addlist($1, $3); 523798Speter | 524798Speter error 525798Speter = { 526798Speter $$ = NIL; 527798Speter Kerror: 528798Speter yyPerror("Malformed statement in case", PSTAT); 529798Speter } 530798Speter | 531798Speter cstat_list error 532798Speter = goto Kerror; 533798Speter ; 534798Speter 535798Speter cstat: 536798Speter const_list ':' stat 537798Speter = $$ = tree4(T_CSTAT, lineof($2), fixlist($1), $3); 538798Speter | 539798Speter YCASELAB stat 540798Speter = $$ = tree4(T_CSTAT, lineof($1), NIL, $2); 541798Speter | 542798Speter /* lambda */ 543798Speter = $$ = NIL; 544798Speter ; 545798Speter 546798Speter /* 547798Speter * STATEMENT 548798Speter */ 549798Speter 550798Speter stat: 551798Speter /* lambda */ 552798Speter = $$ = NIL; 553798Speter | 554798Speter YINT ':' stat 555798Speter = $$ = tree4(T_LABEL, lineof($2), $1 == NIL ? NIL : *hash($1, 1), $3); 556798Speter | 557798Speter proc_id 558798Speter = $$ = tree4(T_PCALL, lineof(yyline), $1, NIL); 559798Speter | 560798Speter proc_id '(' wexpr_list ')' 561798Speter = $$ = tree4(T_PCALL, lineof($2), $1, fixlist($3)); 562798Speter | 563798Speter YID error 564798Speter = goto NSerror; 565798Speter | 566798Speter assign 567798Speter | 568798Speter YBEGIN stat_list YEND 569798Speter = { 570798Speter $$ = tree3(T_BLOCK, lineof($1), fixlist($2)); 571798Speter if ($3 < 0) 572798Speter brerror($1, "begin"); 573798Speter } 574798Speter | 575798Speter YCASE expr YOF cstat_list YEND 576798Speter = { 577798Speter $$ = tree4(T_CASE, lineof($1), $2, fixlist($4)); 578798Speter if ($5 < 0) 579798Speter brerror($1, "case"); 580798Speter } 581798Speter | 582798Speter YWITH var_list YDO stat 583798Speter = $$ = tree4(T_WITH, lineof($1), fixlist($2), $4); 584798Speter | 585798Speter YWHILE expr YDO stat 586798Speter = $$ = tree4(T_WHILE, lineof($1), $2, $4); 587798Speter | 588798Speter YREPEAT stat_list YUNTIL expr 589798Speter = $$ = tree4(T_REPEAT, lineof($3), fixlist($2), $4); 590798Speter | 591798Speter YFOR assign YTO expr YDO stat 592798Speter = $$ = tree5(T_FORU, lineof($1), $2, $4, $6); 593798Speter | 594798Speter YFOR assign YDOWNTO expr YDO stat 595798Speter = $$ = tree5(T_FORD, lineof($1), $2, $4, $6); 596798Speter | 597798Speter YGOTO YINT 598798Speter = $$ = tree3(T_GOTO, lineof($1), *hash($2, 1)); 599798Speter | 600798Speter YIF expr YTHEN stat 601798Speter = $$ = tree5(T_IF, lineof($1), $2, $4, NIL); 602798Speter | 603798Speter YIF expr YTHEN stat YELSE stat 604798Speter = $$ = tree5(T_IFEL, lineof($1), $2, $4, $6); 605798Speter | 606798Speter error 607798Speter = { 608798Speter NSerror: 609798Speter $$ = NIL; 610798Speter Serror: 611798Speter yyPerror("Malformed statement", PSTAT); 612798Speter } 613798Speter ; 614798Speter assign: 615798Speter variable ':' '=' expr 616798Speter = $$ = tree4(T_ASGN, lineof($2), $1, $4); 617798Speter ; 618798Speter 619798Speter /* 620798Speter * EXPRESSION 621798Speter */ 622798Speter 623798Speter expr: 624798Speter error 625798Speter = { 626798Speter NEerror: 627798Speter $$ = NIL; 628798Speter Eerror: 629798Speter yyPerror("Missing/malformed expression", PEXPR); 630798Speter } 631798Speter | 632798Speter expr relop expr %prec '<' 633798Speter = $$ = tree4($2, $1[1] == SAWCON ? $3[1] : $1[1], $1, $3); 634798Speter | 635798Speter '+' expr %prec UNARYSIGN 636798Speter = $$ = tree3(T_PLUS, $2[1], $2); 637798Speter | 638798Speter '-' expr %prec UNARYSIGN 639798Speter = $$ = tree3(T_MINUS, $2[1], $2); 640798Speter | 641798Speter expr addop expr %prec '+' 642798Speter = $$ = tree4($2, $1[1] == SAWCON ? $3[1] : $1[1], $1, $3); 643798Speter | 644798Speter expr divop expr %prec '*' 645798Speter = $$ = tree4($2, $1[1] == SAWCON ? $3[1] : $1[1], $1, $3); 646798Speter | 647798Speter YNIL 648798Speter = $$ = tree2(T_NIL, NOCON); 649798Speter | 650798Speter YSTRING 651798Speter = $$ = tree3(T_STRNG, SAWCON, $1); 652798Speter | 653798Speter YINT 654798Speter = $$ = tree3(T_INT, NOCON, $1); 655798Speter | 656798Speter YBINT 657798Speter = $$ = tree3(T_BINT, NOCON, $1); 658798Speter | 659798Speter YNUMB 660798Speter = $$ = tree3(T_FINT, NOCON, $1); 661798Speter | 662798Speter variable 663798Speter | 664798Speter YID error 665798Speter = goto NEerror; 666798Speter | 667798Speter func_id '(' wexpr_list ')' 668798Speter = $$ = tree4(T_FCALL, NOCON, $1, fixlist($3)); 669798Speter | 670798Speter '(' expr ')' 671798Speter = $$ = $2; 672798Speter | 673798Speter negop expr %prec YNOT 674798Speter = $$ = tree3(T_NOT, NOCON, $2); 675798Speter | 676798Speter '[' element_list ']' 677798Speter = $$ = tree3(T_CSET, SAWCON, fixlist($2)); 678798Speter | 679798Speter '[' ']' 680798Speter = $$ = tree3(T_CSET, SAWCON, NIL); 681798Speter ; 682798Speter 683798Speter element_list: 684798Speter element 685798Speter = $$ = newlist($1); 686798Speter | 687798Speter element_list ',' element 688798Speter = $$ = addlist($1, $3); 689798Speter ; 690798Speter element: 691798Speter expr 692798Speter | 693798Speter expr YDOTDOT expr 694798Speter = $$ = tree3(T_RANG, $1, $3); 695798Speter ; 696798Speter 697798Speter /* 698798Speter * QUALIFIED VARIABLES 699798Speter */ 700798Speter 701798Speter variable: 702798Speter YID 703798Speter = { 704804Speter @@ return (identis(var, VAR)); 705798Speter $$ = setupvar($1, NIL); 706798Speter } 707798Speter | 708798Speter qual_var 709798Speter = $1[3] = fixlist($1[3]); 710798Speter ; 711798Speter qual_var: 712798Speter array_id '[' expr_list ']' 713798Speter = $$ = setupvar($1, tree2(T_ARY, fixlist($3))); 714798Speter | 715798Speter qual_var '[' expr_list ']' 716798Speter = $1[3] = addlist($1[3], tree2(T_ARY, fixlist($3))); 717798Speter | 718798Speter record_id '.' field_id 719798Speter = $$ = setupvar($1, setupfield($3, NIL)); 720798Speter | 721798Speter qual_var '.' field_id 722798Speter = $1[3] = addlist($1[3], setupfield($3, NIL)); 723798Speter | 724798Speter ptr_id '^' 725798Speter = $$ = setupvar($1, tree1(T_PTR)); 726798Speter | 727798Speter qual_var '^' 728798Speter = $1[3] = addlist($1[3], tree1(T_PTR)); 729798Speter ; 730798Speter 731798Speter /* 732798Speter * Expression with write widths 733798Speter */ 734798Speter wexpr: 735798Speter expr 736798Speter | 737798Speter expr ':' expr 738798Speter = $$ = tree4(T_WEXP, $1, $3, NIL); 739798Speter | 740798Speter expr ':' expr ':' expr 741798Speter = $$ = tree4(T_WEXP, $1, $3, $5); 742798Speter | 743798Speter expr octhex 744798Speter = $$ = tree4(T_WEXP, $1, NIL, $2); 745798Speter | 746798Speter expr ':' expr octhex 747798Speter = $$ = tree4(T_WEXP, $1, $3, $4); 748798Speter ; 749798Speter octhex: 750798Speter YOCT 751798Speter = $$ = OCT; 752798Speter | 753798Speter YHEX 754798Speter = $$ = HEX; 755798Speter ; 756798Speter 757798Speter expr_list: 758798Speter expr 759798Speter = $$ = newlist($1); 760798Speter | 761798Speter expr_list ',' expr 762798Speter = $$ = addlist($1, $3); 763798Speter ; 764798Speter 765798Speter wexpr_list: 766798Speter wexpr 767798Speter = $$ = newlist($1); 768798Speter | 769798Speter wexpr_list ',' wexpr 770798Speter = $$ = addlist($1, $3); 771798Speter ; 772798Speter 773798Speter /* 774798Speter * OPERATORS 775798Speter */ 776798Speter 777798Speter relop: 778798Speter '=' = $$ = T_EQ; 779798Speter | 780798Speter '<' = $$ = T_LT; 781798Speter | 782798Speter '>' = $$ = T_GT; 783798Speter | 784798Speter '<' '>' = $$ = T_NE; 785798Speter | 786798Speter '<' '=' = $$ = T_LE; 787798Speter | 788798Speter '>' '=' = $$ = T_GE; 789798Speter | 790798Speter YIN = $$ = T_IN; 791798Speter ; 792798Speter addop: 793798Speter '+' = $$ = T_ADD; 794798Speter | 795798Speter '-' = $$ = T_SUB; 796798Speter | 797798Speter YOR = $$ = T_OR; 798798Speter | 799798Speter '|' = $$ = T_OR; 800798Speter ; 801798Speter divop: 802798Speter '*' = $$ = T_MULT; 803798Speter | 804798Speter '/' = $$ = T_DIVD; 805798Speter | 806798Speter YDIV = $$ = T_DIV; 807798Speter | 808798Speter YMOD = $$ = T_MOD; 809798Speter | 810798Speter YAND = $$ = T_AND; 811798Speter | 812798Speter '&' = $$ = T_AND; 813798Speter ; 814798Speter 815798Speter negop: 816798Speter YNOT 817798Speter | 818798Speter '~' 819798Speter ; 820798Speter 821798Speter /* 822798Speter * LISTS 823798Speter */ 824798Speter 825798Speter var_list: 826798Speter variable 827798Speter = $$ = newlist($1); 828798Speter | 829798Speter var_list ',' variable 830798Speter = $$ = addlist($1, $3); 831798Speter ; 832798Speter 833798Speter id_list: 834798Speter YID 835798Speter = $$ = newlist($1); 836798Speter | 837798Speter id_list ',' YID 838798Speter = $$ = addlist($1, $3); 839798Speter ; 840798Speter 841798Speter /* 842798Speter * Identifier productions with semantic restrictions 843798Speter * 844804Speter * For these productions, the characters @@ signify 845798Speter * that the associated C statement is to provide 846798Speter * the semantic restriction for this reduction. 847798Speter * These lines are made into a procedure yyEactr, similar to 848798Speter * yyactr, which determines whether the corresponding reduction 849798Speter * is permitted, or whether an error is to be signaled. 850798Speter * A zero return from yyEactr is considered an error. 851798Speter * YyEactr is called with an argument "var" giving the string 852798Speter * name of the variable in question, essentially $1, although 853798Speter * $1 will not work because yyEactr is called from loccor in 854798Speter * the recovery routines. 855798Speter */ 856798Speter 857798Speter const_id: 858798Speter YID 859804Speter = @@ return (identis(var, CONST)); 860798Speter ; 861798Speter type_id: 862798Speter YID 863798Speter = { 864804Speter @@ return (identis(var, TYPE)); 865798Speter $$ = tree3(T_TYID, lineof(yyline), $1); 866798Speter } 867798Speter ; 868798Speter var_id: 869798Speter YID 870804Speter = @@ return (identis(var, VAR)); 871798Speter ; 872798Speter array_id: 873798Speter YID 874804Speter = @@ return (identis(var, ARRAY)); 875798Speter ; 876798Speter ptr_id: 877798Speter YID 878804Speter = @@ return (identis(var, PTRFILE)); 879798Speter ; 880798Speter record_id: 881798Speter YID 882804Speter = @@ return (identis(var, RECORD)); 883798Speter ; 884798Speter field_id: 885798Speter YID 886804Speter = @@ return (identis(var, FIELD)); 887798Speter ; 888798Speter proc_id: 889798Speter YID 890804Speter = @@ return (identis(var, PROC)); 891798Speter ; 892798Speter func_id: 893798Speter YID 894804Speter = @@ return (identis(var, FUNC)); 895798Speter ; 896