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