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

Defined macros

line2of defined in line 117; used 4 times
lineof defined in line 116; used 46 times
Last modified: 1985-06-21
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2015
Valid CSS Valid XHTML 1.0 Strict