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