|
|
1.1 ! root 1: /*ident "@(#)ctrans:src/gram.y 1.6.5.35" */ ! 2: /************************************************************************* ! 3: ! 4: C++ source for cfront, the C++ compiler front-end ! 5: written in the computer science research center of Bell Labs ! 6: ! 7: Copyright (c) 1984 AT&T, Inc. All Rights Reserved ! 8: THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T, INC. ! 9: ! 10: gram.y: ! 11: ! 12: This is the C++ syntax analyser. ! 13: ! 14: Syntax extensions for error handling: ! 15: nested functions ! 16: any expression can be empty ! 17: any expression can be a constant_expression ! 18: ! 19: A call to error() does not change the parser's state ! 20: ! 21: ***************************************************************************/ ! 22: ! 23: %{ ! 24: #include "cfront.h" ! 25: #include "size.h" ! 26: // include tqueue.h after YYSTYPE is defined ... ! 27: ! 28: #define YYMAXDEPTH 600 ! 29: ! 30: #ifdef DBG ! 31: #ifndef YYDEBUG ! 32: #define YYDEBUG 1 ! 33: #endif ! 34: #endif ! 35: ! 36: static init_seen = 0; ! 37: static cdi = 0; ! 38: static Pnlist cd = 0, cd_vec[BLMAX]; ! 39: static char stmt_seen = 0, stmt_vec[BLMAX]; ! 40: ! 41: //local class ! 42: static Plist tn_vec[BLMAX], lcl_tn_vec[BLMAX], lcl_blk_vec[BLMAX]; ! 43: extern void local_restore(); ! 44: extern void local_name(); ! 45: ! 46: //nested class ! 47: static Plist nested_tn_vec[BLMAX], nested_type_vec[BLMAX]; ! 48: extern void nested_restore(); ! 49: extern char *class_typedef; ! 50: ! 51: static Pname err_name = 0; ! 52: ! 53: // fcts put into norm2.c just to get them out of gram.y ! 54: void sig_name(Pname); ! 55: Ptype tok_to_type(TOK); ! 56: void memptrdcl(Pname, Pname, Ptype, Pname); ! 57: ! 58: static Pptr doptr(TOK p, TOK t) ! 59: { ! 60: Pptr r = new ptr(p,0); ! 61: switch (t) { ! 62: case CONST: ! 63: r->rdo = 1; ! 64: // if (p == RPTR) error('w',"redundant `const' after &"); ! 65: break; ! 66: case VOLATILE: ! 67: error('w',"\"volatile\" not implemented (ignored)"); ! 68: break; ! 69: default: ! 70: error("syntax error: *%k",t); ! 71: } ! 72: return r; ! 73: } ! 74: ! 75: static Pbcl dobase(TOK pr, Pname n, TOK v = 0) ! 76: { ! 77: Pbcl b = new basecl(0,0); ! 78: ! 79: if (pr == PROTECTED) { ! 80: pr = PUBLIC; ! 81: error("protectedBC"); ! 82: } ! 83: b->ppp = pr; // save protection indicator ! 84: ! 85: if (n) { ! 86: if (n->base != TNAME) { ! 87: error("BN%n not aTN",n); ! 88: return 0; ! 89: } ! 90: ! 91: Pbase bt = Pbase(n->tp); ! 92: while (bt->base == TYPE) bt = Pbase(bt->b_name->tp); ! 93: ! 94: if (bt->base != COBJ) { ! 95: error("BN%n not aCN",n); ! 96: return 0; ! 97: } ! 98: ! 99: if (v) { ! 100: if (v != VIRTUAL) error("syntax error:%k inBCD",v); ! 101: b->base = VIRTUAL; ! 102: } ! 103: else ! 104: b->base = NAME; ! 105: ! 106: b->bclass = Pclass(bt->b_name->tp); ! 107: } ! 108: ! 109: return b; ! 110: } ! 111: ! 112: ! 113: #define Ndata(a,b) b->normalize(Pbase(a),0,0) ! 114: #define Ncast(a,b) b->normalize(Pbase(a),0,1) ! 115: #define Nfct(a,b,c) b->normalize(Pbase(a),Pblock(c),0) ! 116: #define Ncopy(n) (n->base==TNAME)?new name(n->string):n ! 117: ! 118: #define Finit(p) Pfct(p)->f_init ! 119: #define Fargdcl(p,q,r) Pfct(p)->argdcl(q,r) ! 120: #define Freturns(p) Pfct(p)->returns ! 121: #define Vtype(v) Pvec(v)->typ ! 122: #define Ptyp(p) Pptr(p)->typ ! 123: ! 124: /* avoid redefinitions */ ! 125: #undef EOFTOK ! 126: #undef ASM ! 127: #undef BREAK ! 128: #undef CASE ! 129: #undef CONTINUE ! 130: #undef DEFAULT ! 131: #undef DELETE ! 132: #undef DO ! 133: #undef ELSE ! 134: #undef ENUM ! 135: #undef FOR ! 136: #undef FORTRAN ! 137: #undef GOTO ! 138: #undef IF ! 139: #undef NEW ! 140: #undef OPERATOR ! 141: #undef RETURN ! 142: #undef SIZEOF ! 143: #undef SWITCH ! 144: #undef THIS ! 145: #undef WHILE ! 146: #undef LP ! 147: #undef RP ! 148: #undef LB ! 149: #undef RB ! 150: #undef REF ! 151: #undef DOT ! 152: #undef NOT ! 153: #undef COMPL ! 154: #undef MUL ! 155: #undef AND ! 156: #undef PLUS ! 157: #undef MINUS ! 158: #undef ER ! 159: #undef OR ! 160: #undef ANDAND ! 161: #undef OROR ! 162: #undef QUEST ! 163: #undef COLON ! 164: #undef ASSIGN ! 165: #undef CM ! 166: #undef SM ! 167: #undef LC ! 168: #undef RC ! 169: #undef ID ! 170: #undef STRING ! 171: #undef ICON ! 172: #undef FCON ! 173: #undef CCON ! 174: #undef ZERO ! 175: #undef ASOP ! 176: #undef RELOP ! 177: #undef EQUOP ! 178: #undef DIVOP ! 179: #undef SHIFTOP ! 180: #undef ICOP ! 181: #undef TYPE ! 182: #undef TNAME ! 183: #undef EMPTY ! 184: #undef NO_ID ! 185: #undef NO_EXPR ! 186: #undef FDEF ! 187: #undef ELLIPSIS ! 188: #undef AGGR ! 189: #undef MEM ! 190: #undef MEMPTR ! 191: #undef PR ! 192: #undef TSCOPE ! 193: #undef DECL_MARKER ! 194: #undef REFMUL ! 195: #undef LDOUBLE ! 196: #undef LINKAGE ! 197: #undef LOCAL ! 198: #undef NESTED ! 199: %} ! 200: ! 201: %union { ! 202: char* s; ! 203: TOK t; ! 204: int i; ! 205: loc l; ! 206: Pname pn; ! 207: Ptype pt; ! 208: Pexpr pe; ! 209: Pstmt ps; ! 210: Pbase pb; ! 211: Pnlist nl; ! 212: Pslist sl; ! 213: Pelist el; ! 214: Pbcl pbc; ! 215: Pptr pp; ! 216: PP p; // fudge: pointer to all class node objects ! 217: Plist pl; ! 218: toknode* q; // token queue ! 219: } ! 220: %{ ! 221: #include "tqueue.h" ! 222: extern YYSTYPE yylval, yyval; ! 223: extern int yyparse(); ! 224: ! 225: // in_typedef should allow for nested in_typedef ! 226: extern int declTag; // !1: inline, virtual mod permitted ! 227: int in_sizeof = 0; ! 228: Ptype in_typedef = 0; // catch redefinition of TNAME ! 229: Pname in_tag = 0; // handle complex typedefs: int (*)() ! 230: extern int defer_check; // redefinition typedef check delay ! 231: Pname curr_scope; ! 232: ! 233: extern int must_be_id; // !0, TNAME => ID, i.e., int X ! 234: int DECL_TYPE = 0; // lalex() wants this set for global x(*fp)() ! 235: int in_arg_list=0; // !0 when parsing argument list ! 236: static int in_binit_list=0; ! 237: int in_class_decl=0; // !0 when processing class definition ! 238: int parsing_class_members=0; // !0 when parsing class def but not member function body ! 239: int in_mem_fct=0; // !0 when parsing member function definition ! 240: ! 241: #define yylex lalex ! 242: #define NEXTTOK() ( (yychar==-1) ? (yychar=yylex(),yychar) : yychar ) ! 243: #define EXPECT_ID() must_be_id = 1 ! 244: #define NOT_EXPECT_ID() must_be_id = 0 ! 245: ! 246: Pname syn() ! 247: { ! 248: ll: ! 249: switch (yyparse()) { ! 250: case 0: return 0; // EOF ! 251: case 1: goto ll; // no action needed ! 252: default: return yyval.pn; ! 253: } ! 254: } ! 255: ! 256: %} ! 257: /* ! 258: the token definitions are copied from token.h, ! 259: and all %token replaced by %token ! 260: */ ! 261: /* keywords in alphabetical order */ ! 262: %token EOFTOK 0 ! 263: %token ASM 1 ! 264: %token BREAK 3 ! 265: %token CASE 4 ! 266: %token CONTINUE 7 ! 267: %token DEFAULT 8 ! 268: %token DELETE 9 ! 269: %token DO 10 ! 270: %token ELSE 12 ! 271: %token ENUM 13 ! 272: %token FOR 16 ! 273: %token FORTRAN 17 ! 274: %token GOTO 19 ! 275: %token IF 20 ! 276: %token NEW 23 ! 277: %token OPERATOR 24 ! 278: %token RETURN 28 ! 279: %token SIZEOF 30 ! 280: %token SWITCH 33 ! 281: %token THIS 34 ! 282: %token WHILE 39 ! 283: ! 284: /* operators in priority order (sort of) */ ! 285: %token LP 40 ! 286: %token RP 41 ! 287: %token LB 42 ! 288: %token RB 43 ! 289: %token REF 44 ! 290: %token DOT 45 ! 291: %token NOT 46 ! 292: %token COMPL 47 ! 293: %token MUL 50 ! 294: %token AND 52 ! 295: %token PLUS 54 ! 296: %token MINUS 55 ! 297: %token ER 64 ! 298: %token OR 65 ! 299: %token ANDAND 66 ! 300: %token OROR 67 ! 301: %token QUEST 68 ! 302: %token COLON 69 ! 303: %token ASSIGN 70 ! 304: %token CM 71 ! 305: %token SM 72 ! 306: %token LC 73 ! 307: %token RC 74 ! 308: %token MEMPTR 173 ! 309: ! 310: /* constants etc. */ ! 311: %token ID 80 ! 312: %token STRING 81 ! 313: %token ICON 82 ! 314: %token FCON 83 ! 315: %token CCON 84 ! 316: ! 317: %token ZERO 86 ! 318: ! 319: /* groups of tokens */ ! 320: %token ASOP 90 /* op= */ ! 321: %token RELOP 91 /* LE GE LT GT */ ! 322: %token EQUOP 92 /* EQ NE */ ! 323: %token DIVOP 93 /* DIV MOD */ ! 324: %token SHIFTOP 94 /* LS RS */ ! 325: %token ICOP 95 /* INCR DECR */ ! 326: ! 327: %token TYPE 97 /* INT FLOAT CHAR DOUBLE ! 328: REGISTER STATIC EXTERN AUTO ! 329: CONST INLINE VIRTUAL FRIEND ! 330: LONG SHORT UNSIGNED OVERLOAD ! 331: TYPEDEF */ ! 332: %token TNAME 123 ! 333: %token EMPTY 124 ! 334: %token NO_ID 125 ! 335: %token NO_EXPR 126 ! 336: %token FDEF 127 ! 337: %token ELLIPSIS 155 /* ... */ ! 338: %token AGGR 156 /* CLASS STRUCT UNION */ ! 339: %token MEM 160 /* :: */ ! 340: %token PR 175 /* PUBLIC PRIVATE PROTECTED */ ! 341: %token TSCOPE 178 /* TNAME :: */ ! 342: %token DECL_MARKER 179 ! 343: %token REFMUL 180 /* ->*, .* */ ! 344: %token LDOUBLE 181 ! 345: %token LINKAGE 182 /* extern "asdf" */ ! 346: %token LOCAL 183 /* local class */ ! 347: %token NESTED 190 /* nested class */ ! 348: ! 349: %type <p> external_def fct_dcl fct_def att_fct_def arg_dcl_list ! 350: base_init init_list binit ! 351: data_dcl ext_def vec ptr ! 352: type tp enum_dcl moe_list ! 353: moe ! 354: tag enumtag class_head class_dcl cl_mem_list ! 355: cl_mem dl decl_list ! 356: fname decl initializer stmt_list ! 357: caselab_stmt caselablist ! 358: block statement simple ex_list elist e ee term prim ! 359: term_elist ! 360: cast_decl cast_type c_decl c_type c_tp ! 361: arg_decl at arg_type arg_list arg_type_list ! 362: new_decl new_type ! 363: condition ! 364: TSCOPE tscope TNAME tn_list MEMPTR ! 365: qualified_tname ! 366: %type <l> LC RC SWITCH CASE DEFAULT FOR IF DO WHILE GOTO RETURN DELETE ! 367: BREAK CONTINUE ! 368: %type <t> oper ellipsis_opt ! 369: EQUOP DIVOP SHIFTOP ICOP RELOP ASOP ! 370: ANDAND OROR PLUS MINUS MUL ASSIGN OR ER AND ! 371: LP LB NOT COMPL AGGR ! 372: TYPE PR REFMUL ! 373: %type <s> CCON ZERO ICON FCON STRING LINKAGE ! 374: %type <pn> ID FDEF inline_fct_def ! 375: %type <pbc> base_list base_unit_list base_unit ! 376: %type <q> EMPTY ! 377: %type <i> fct_attributes ! 378: %type <pl> arg_lp ! 379: ! 380: %left EMPTY ! 381: %left NO_ID ! 382: %left RC LC ID BREAK CONTINUE RETURN GOTO DELETE DO IF WHILE FOR CASE DEFAULT ! 383: AGGR ENUM TYPE TNAME TSCOPE ! 384: %left NO_EXPR ! 385: ! 386: %left CM ! 387: %right ASOP ASSIGN ! 388: %right QUEST COLON ! 389: %left OROR ! 390: %left ANDAND ! 391: %left OR ! 392: %left ER ! 393: %left AND ! 394: %left EQUOP ! 395: %left RELOP ! 396: %left SHIFTOP ! 397: %left PLUS MINUS ! 398: %left MUL DIVOP MEMPTR ! 399: %left REFMUL ! 400: %right NOT COMPL NEW ! 401: %right ICOP SIZEOF ! 402: %left LB LP DOT REF MEM ! 403: ! 404: %start ext_def ! 405: ! 406: %% ! 407: /* ! 408: this parser handles declarations one by one, ! 409: NOT a complete .c file ! 410: */ ! 411: ! 412: ! 413: /************** DECLARATIONS in the outermost scope: returns Pname (in yylval) ***/ ! 414: ! 415: ext_def : external_def { return 2; } ! 416: | SM { return 1; } ! 417: | EOFTOK { return 0; } ! 418: | LINKAGE LC ! 419: { ! 420: set_linkage($<s>1); ! 421: bl_level--; ! 422: return 1; ! 423: } ! 424: | RC ! 425: { ! 426: set_linkage(0); ! 427: bl_level++; ! 428: return 1; ! 429: } ! 430: ; ! 431: ! 432: external_def : data_dcl ! 433: { ! 434: /* if function declartion with arguments ! 435: * need to make sure modified_tn is traversed */ ! 436: if ( $<pn>1 != 0 ! 437: && $<pn>1->tp->base == FCT ! 438: && Pfct($<pn>1->tp)->nargs !=0 ) ! 439: goto mod; ! 440: else { ! 441: modified_tn = 0; ! 442: curr_scope = 0; ! 443: if ($<pn>1==0) $<i>$ = 1; ! 444: } ! 445: } ! 446: | att_fct_def ! 447: { goto mod; } ! 448: | fct_def ! 449: { goto mod; } ! 450: | fct_dcl ! 451: { mod: if (modified_tn) { ! 452: restore(); ! 453: modified_tn = 0; ! 454: } ! 455: local_blk = 0; ! 456: curr_scope = 0; ! 457: if (local_tn) { ! 458: local_restore(); ! 459: local_tn = 0; ! 460: } ! 461: ! 462: if (nested_tn) { // x::f(){} ! 463: nested_restore(); ! 464: nested_tn = 0; ! 465: nested_type = 0; ! 466: } ! 467: } ! 468: | ASM LP STRING RP SM ! 469: { Pname n = new name(make_name('A')); ! 470: n->tp = new basetype(ASM,0); ! 471: Pbase(n->tp)->b_name = Pname($<s>3); ! 472: $$ = n; ! 473: } ! 474: ; ! 475: ! 476: fct_dcl : decl ASSIGN initializer SM ! 477: { ! 478: err_name = $<pn>1; ! 479: if(err_name) err_name->n_initializer = $<pe>3; ! 480: goto fix; ! 481: } ! 482: | decl SM ! 483: { ! 484: Ptype t; ! 485: err_name = $<pn>1; ! 486: fix: ! 487: if (err_name == 0) { ! 488: error("syntax error:TX"); ! 489: $$ = Ndata(defa_type,err_name); ! 490: } ! 491: else if ((t=err_name->tp) == 0) { ! 492: error("TX for%n",err_name); ! 493: $$ = Ndata(defa_type,err_name); ! 494: } ! 495: else if (t->base==FCT) { ! 496: if (Pfct(t)->returns==0) ! 497: $$ = Nfct(defa_type,err_name,0); ! 498: else ! 499: $$ = Ndata(0,err_name); ! 500: } ! 501: else { ! 502: error("syntax error:TX for%k%n",t->base,err_name); ! 503: $$ = Ndata(defa_type,err_name); ! 504: } ! 505: } ! 506: ; ! 507: ! 508: att_fct_def : type decl arg_dcl_list check_inline base_init block ! 509: { Pname n = Nfct($1,$<pn>2,$6); ! 510: Fargdcl(n->tp,name_unlist($<nl>3),n); ! 511: Finit(n->tp) = $<pn>5; ! 512: $$ = n; ! 513: NOT_EXPECT_ID(); ! 514: } ! 515: | type decl arg_dcl_list check_inline EMPTY ! 516: { ! 517: Pname n = Nfct($1,$<pn>2,dummy); ! 518: Fargdcl(n->tp,name_unlist($<nl>3),n); ! 519: $<q>5->retval.pn = n; ! 520: $$ = n; ! 521: NOT_EXPECT_ID(); ! 522: } ! 523: | type decl arg_dcl_list check_inline NO_ID /*syntax error*/ ! 524: { ! 525: error(&$<pn>2->where,"syntax error -- did you forget a ';'?"); ! 526: Pname n = Nfct($1,$<pn>2,0); ! 527: $$ = n; ! 528: NOT_EXPECT_ID(); ! 529: } ! 530: ; ! 531: ! 532: fct_def : decl arg_dcl_list check_inline base_init block ! 533: { Pname n = Nfct(defa_type,$<pn>1,$5); ! 534: Fargdcl(n->tp,name_unlist($<nl>2),n); ! 535: if ( $<pn>4 && $<pn>4->n_list && ! 536: ccl && ccl->csu == UNION ) ! 537: error( "multiple initializers in unionK %s::%n", $<pn>1->string, $<pn>1 ); ! 538: Finit(n->tp) = $<pn>4; ! 539: $$ = n; ! 540: NOT_EXPECT_ID(); ! 541: } ! 542: | decl arg_dcl_list check_inline EMPTY ! 543: { ! 544: Pname n = Nfct(defa_type,$<pn>1,dummy); ! 545: Fargdcl(n->tp,name_unlist($<nl>2),n); ! 546: $<q>4->retval.pn = n; ! 547: $$ = n; ! 548: NOT_EXPECT_ID(); ! 549: } ! 550: | decl arg_dcl_list check_inline NO_ID /*syntax error*/ ! 551: { ! 552: error(&$<pn>1->where,"badD of%n -- did you forget a ';'?",$<pn>1); ! 553: Pname n = Nfct(defa_type,$<pn>1,0); ! 554: $$ = n; ! 555: NOT_EXPECT_ID(); ! 556: } ! 557: ; ! 558: ! 559: inline_fct_def : FDEF { arg_redec($<pn>1); } ! 560: base_init block ! 561: { ! 562: Finit($1->tp) = $<pn>3; ! 563: Pfct($1->tp)->body = Pblock($4); ! 564: $$ = $1; ! 565: NOT_EXPECT_ID(); ! 566: } ! 567: ; ! 568: ! 569: ! 570: check_inline : /* empty */ ! 571: { ! 572: // if parsing implicit inline def, save body ! 573: // of function for parsing after class def ! 574: switch ( NEXTTOK() ) { ! 575: case LC: case COLON: ! 576: if ( in_class_decl ) { ! 577: // mem or friend inline def ! 578: // save text of mem_init & ftn ! 579: la_backup(yychar,yylval); ! 580: // yylval used as dummy... ! 581: la_backup(FDEF, yylval); ! 582: if ( yylval.q = save_text() ) ! 583: yychar = EMPTY; ! 584: else { // syntax error ! 585: // just parse in place ! 586: yylex(); // FDEF ! 587: yychar = yylex(); ! 588: } ! 589: } // if in_class_decl ! 590: break; ! 591: default: ! 592: la_backup(yychar,yylval); ! 593: yychar = NO_ID; // 'graceful' recovery ! 594: break; ! 595: } ! 596: } ! 597: ; ! 598: ! 599: base_init : COLON { ++in_binit_list; } init_list ! 600: { ! 601: $$ = $3; ! 602: in_arg_list = 0; ! 603: --in_binit_list; ! 604: } ! 605: | %prec EMPTY ! 606: { $$ = 0; } ! 607: ; ! 608: ! 609: init_list : binit ! 610: { $$ = $1; } ! 611: | init_list CM binit ! 612: { $<pn>$ = $<pn>3; $<pn>$->n_list = $<pn>1; } ! 613: ; ! 614: ! 615: binit : LP elist RP ! 616: { ! 617: $<pn>$ = new name; ! 618: $<pn>$->n_initializer = $<pe>2; ! 619: } ! 620: | tag LP elist RP ! 621: { ! 622: Pname n = Ncopy($<pn>1); ! 623: n->base = $<pn>1->base; ! 624: n->tp = $<pn>1->tp; ! 625: n->n_initializer = $<pe>3; ! 626: $<pn>$ = n; ! 627: } ! 628: ! 629: /* ! 630: | NEW LP elist RP ! 631: { Pname n = new name; ! 632: n->base = NEW; ! 633: n->n_initializer = $<pe>3; ! 634: $<pn>$ = n; ! 635: } ! 636: */ ! 637: ; ! 638: ! 639: ! 640: ! 641: ! 642: /*************** declarations: returns Pname ********************/ ! 643: ! 644: arg_dcl_list : arg_dcl_list data_dcl ! 645: { if ($<pn>2 == 0) ! 646: error("badAD"); ! 647: else if ($<pn>2->tp->base == FCT) ! 648: error("FD inAL (%n)",$<pn>2); ! 649: else if ($1) ! 650: $<nl>1->add_list($<pn>2); ! 651: else ! 652: $<nl>$ = new nlist($<pn>2); ! 653: } ! 654: | %prec EMPTY ! 655: { ! 656: $$ = 0; ! 657: } ! 658: ; ! 659: ! 660: dl : decl ! 661: | ID COLON e %prec CM ! 662: { $$ = $<pn>1; ! 663: $<pn>$->tp = new basetype(FIELD,$<pn>3); ! 664: } ! 665: | COLON e %prec CM ! 666: { $$ = new name; ! 667: $<pn>$->tp = new basetype(FIELD,$<pn>2); ! 668: } ! 669: | decl ASSIGN initializer ! 670: { Pexpr e = $<pe>3; ! 671: if (e == dummy) error("emptyIr"); ! 672: $<pn>1->n_initializer = e; ! 673: init_seen = 0; ! 674: } ! 675: ; ! 676: ! 677: decl_list : dl ! 678: { ! 679: if ($1) $<nl>$ = new nlist($<pn>1); ! 680: if ( NEXTTOK() == CM && la_look() == TNAME ) ! 681: EXPECT_ID(); ! 682: } ! 683: | decl_list CM dl ! 684: { if ($1) ! 685: if ($3) ! 686: $<nl>1->add($<pn>3); ! 687: else ! 688: error("DL syntax"); ! 689: else { ! 690: if ($3) $<nl>$ = new nlist($<pn>3); ! 691: error("DL syntax"); ! 692: } ! 693: if ( NEXTTOK() == CM && la_look() == TNAME ) ! 694: EXPECT_ID(); ! 695: } ! 696: ; ! 697: ! 698: data_dcl : type decl_list SM ! 699: { ! 700: extern int co_hack; ! 701: co_hack = 1; ! 702: /*$$ = Ndata($1,name_unlist($<nl>2));*/ ! 703: Pname n = Ndata($1,name_unlist($<nl>2)); ! 704: if ( in_typedef && in_tag ) { ! 705: if ( n->tp->check( in_tag->tp, 0 )) ! 706: error("%nredefined: previous: %t now: %t", in_tag, in_tag->tp, n->tp ); ! 707: } ! 708: in_typedef = 0; ! 709: class_typedef = 0; ! 710: in_tag = 0; ! 711: co_hack = 0; ! 712: DECL_TYPE = 0; ! 713: $$ = n; ! 714: } ! 715: | type SM ! 716: { ! 717: $$ = $<pb>1->aggr(); ! 718: in_typedef = 0; ! 719: class_typedef = 0; ! 720: in_tag = 0; ! 721: DECL_TYPE = 0; ! 722: } ! 723: ! 724: ; ! 725: ! 726: tp : TYPE ! 727: { ! 728: $$ = new basetype($<t>1,0); ! 729: if ( $<t>1 == TYPEDEF ) in_typedef = $<pt>$; ! 730: if (DECL_TYPE == -1) DECL_TYPE = 0; ! 731: } ! 732: | LINKAGE ! 733: { $$ = new basetype(EXTERN,0); ! 734: $<pb>$->b_linkage = $<s>1; ! 735: if (DECL_TYPE == -1) DECL_TYPE = 0; ! 736: } ! 737: | qualified_tname ! 738: { ! 739: $$ = new basetype(TYPE,$<pn>1); ! 740: if (DECL_TYPE == -1) DECL_TYPE = 0; ! 741: } ! 742: /*XXX*/ | tn_list DECL_MARKER ! 743: { // modified tn_list TNAME ! 744: $$ = new basetype(TYPE,$<pn>2); ! 745: //xxx qualifier currently ignored... ! 746: if (DECL_TYPE == -1) DECL_TYPE = 0; ! 747: } ! 748: | class_dcl ! 749: | enum_dcl ! 750: | DECL_MARKER ! 751: { ! 752: if (DECL_TYPE == TNAME) ! 753: $$ = new basetype(TYPE,$<pn>1); ! 754: // else if (DECL_TYPE == TSCOPE) ! 755: // $$ = 0; ! 756: else ! 757: if (DECL_TYPE == 0 && ! 758: $<p>1->base == TNAME) ! 759: $$ = new basetype(TYPE,$<pn>1); ! 760: else ! 761: $$ = new basetype($<t>1,0); ! 762: DECL_TYPE = -1; ! 763: } ! 764: ; ! 765: ! 766: type : tp ! 767: | type TYPE ! 768: { ! 769: if ( DECL_TYPE != -1 ) ! 770: $$ = $<pb>1->type_adj($<t>2); ! 771: DECL_TYPE = 0; ! 772: } ! 773: | type qualified_tname ! 774: { ! 775: //error('d',"decl_type: %d $1: %t $2: %n",DECL_TYPE,$<pb>1,$<pn>2); ! 776: if ( DECL_TYPE != -1 ) ! 777: $$ = $<pb>1->name_adj($<pn>2); ! 778: /*XXX*/ else if($<pb>1==0) $$=new basetype(TYPE,$<pn>2); ! 779: DECL_TYPE = 0; ! 780: } ! 781: | type class_dcl { $$ = $<pb>1->base_adj($<pb>2); } ! 782: | type enum_dcl { $$ = $<pb>1->base_adj($<pb>2); } ! 783: | type DECL_MARKER ! 784: { ! 785: if (DECL_TYPE == TYPE) ! 786: $$ = $<pb>1->type_adj($<t>2); ! 787: /*XXX*/ else if (DECL_TYPE == TSCOPE) { ! 788: /*XXX*/ error('i',"type decl_marker(tscope)"); ! 789: /*XXX*/ // $$ = $1;//ignore(?) ! 790: /*XXX*/ } ! 791: else ! 792: $$ = $<pb>1->name_adj($<pn>2); ! 793: DECL_TYPE = -1; ! 794: } ! 795: ; ! 796: ! 797: /***************** aggregate: returns Pname *****************/ ! 798: ! 799: enumtag : tag ! 800: { enumcheck: ! 801: Ptype tx = $<pn>1->tp; ! 802: $$ = $1; ! 803: if ( tx->base == TYPE ) { ! 804: $$ = Pbase(tx)->b_name; ! 805: tx = $<pn>$->tp; ! 806: if ( tx->base != EOBJ ! 807: || strcmp($<pn>$->string,$<pn>1->string) ! 808: ) ! 809: error("%n of type%t redeclared as enum.",$<pn>1,tx); ! 810: } else if ( tx->base != EOBJ ) ! 811: error("%n of type%t redeclared as enum",$<pn>1,tx); ! 812: } ! 813: | DECL_MARKER { goto enumcheck; } ! 814: ; ! 815: ! 816: enum_dcl : ENUM LC moe_list RC { $$ = end_enum(0,$<pn>3); } ! 817: | ENUM enumtag LC moe_list RC { $$ = end_enum($<pn>2,$<pn>4); } ! 818: | ENUM enumtag { $<pb>$ = (Pbase)$<pn>2->tp; } ! 819: ; ! 820: ! 821: moe_list : moe ! 822: { if ($1) $<nl>$ = new nlist($<pn>1); } ! 823: | moe_list CM moe ! 824: { if( $3) ! 825: if ($1) ! 826: $<nl>1->add($<pn>3); ! 827: else ! 828: $<nl>$ = new nlist($<pn>3); ! 829: } ! 830: ; ! 831: ! 832: moe : ID ! 833: { $$ = $<pn>1; $<pn>$->tp = moe_type; } ! 834: | ID ASSIGN e ! 835: { $$ = $<pn>1; ! 836: $<pn>$->tp = moe_type; ! 837: $<pn>$->n_initializer = $<pe>3; ! 838: } ! 839: | /* empty: handle trailing CM: enum e { a,b, }; */ ! 840: { $$ = 0; } ! 841: ; ! 842: ! 843: class_dcl : class_head cl_mem_list RC ! 844: { parsing_class_members = 0; ! 845: switch ( NEXTTOK() ) { ! 846: case TYPE: case AGGR: case ENUM: case EOFTOK: ! 847: error("`;' or declaratorX afterCD"); ! 848: la_backup(yychar,yylval); ! 849: yychar = SM; ! 850: break; ! 851: } ! 852: la_backup(yychar,yylval); ! 853: yychar = -1; ! 854: restore_text(); ! 855: ++bl_level; // scope weirdness! ! 856: ++in_mem_fct; ! 857: } ! 858: inline_mem_defs ! 859: { ! 860: --in_mem_fct; ! 861: --bl_level; // scope weirdness! ! 862: if ( yychar == ID ) { ! 863: // (yuk!) adjust lex level ! 864: --yylval.pn->lex_level; ! 865: } ! 866: ccl->mem_list = name_unlist($<nl>2); ! 867: if ( --in_class_decl ) // nested class ! 868: // continue to parse enclosing class ! 869: parsing_class_members = 1; ! 870: ccl->nest_list = nested_type; ! 871: if ( nested_tn ) nested_restore(); ! 872: nested_type = nested_type_vec[in_class_decl]; ! 873: nested_tn = nested_tn_vec[in_class_decl]; ! 874: end_cl(); ! 875: declTag = 1; ! 876: } ! 877: | AGGR tag ! 878: { aggrcheck: ! 879: $<pb>$ = (Pbase)$<pn>2->tp; ! 880: if ( $$->base == TYPE ) { ! 881: Pname nx = $<pb>$->b_name; ! 882: $<pb>$ = (Pbase)nx->tp; ! 883: if ( $$->base != COBJ ! 884: || strcmp(nx->string,$<pn>2->string) ! 885: ) ! 886: error("%n of type%t redeclared as%k.",$<pn>2,$<pb>$,$<t>1); ! 887: } else if ( $$->base != COBJ ) ! 888: error("%n of type%t redeclared as%k",$<pn>2,$<pb>$,$<t>1); ! 889: check_tag(); ! 890: } ! 891: ! 892: | AGGR DECL_MARKER ! 893: { ! 894: goto aggrcheck; ! 895: } ! 896: ; ! 897: ! 898: ! 899: inline_mem_defs : /* empty */ ! 900: | inline_mem_defs inline_fct_def ! 901: ; ! 902: ! 903: base_list : COLON base_unit_list { $$ = $2; } ! 904: | %prec EMPTY { $$ = 0; } ! 905: ; ! 906: ! 907: base_unit_list : base_unit ! 908: | base_unit_list CM base_unit ! 909: { if ($3) { $$ = $3; $<pbc>$->next = $1; } } ! 910: ; ! 911: ! 912: base_unit : tag { $$ = dobase(0,$<pn>1); } ! 913: | PR tag { $$ = dobase($<t>1,$<pn>2); } ! 914: | TYPE tag { $$ = dobase(0,$<pn>2,$<t>1); } ! 915: | PR TYPE tag { $$ = dobase($<t>1,$<pn>3,$<t>2); } ! 916: | TYPE PR tag { $$ = dobase($<t>2,$<pn>3,$<t>1); } ! 917: ; ! 918: ! 919: class_head : AGGR LC ! 920: { parsing_class_members = 1; ! 921: $$ = start_cl($<t>1,0,0); ! 922: nested_tn_vec[in_class_decl] = nested_tn; ! 923: nested_type_vec[in_class_decl++] = nested_type; ! 924: nested_tn = nested_type = 0; ! 925: } ! 926: ! 927: | AGGR tag base_list LC ! 928: { parsing_class_members = 1; ! 929: $$ = start_cl($<t>1,$<pn>2,$<pbc>3); ! 930: nested_tn_vec[in_class_decl] = nested_tn; ! 931: nested_type_vec[in_class_decl++] = nested_type; ! 932: nested_tn = nested_type = 0; ! 933: } ! 934: ; ! 935: ! 936: tag : ID { $$ = $1; } ! 937: | qualified_tname { $$=$1; } ! 938: ; ! 939: ! 940: cl_mem_list : cl_mem_list cl_mem ! 941: { ! 942: if ($2) { ! 943: if ($1) ! 944: $<nl>1->add_list($<pn>2); ! 945: else ! 946: $<nl>$ = new nlist($<pn>2); ! 947: } ! 948: } ! 949: | %prec EMPTY ! 950: { $$ = 0; } ! 951: ; ! 952: ! 953: cl_mem : data_dcl ! 954: | att_fct_def SM ! 955: | fct_def SM ! 956: | fct_def ! 957: | att_fct_def ! 958: | fct_dcl ! 959: | PR COLON ! 960: { $$ = new name; ! 961: $<pn>$->base = $<t>1; ! 962: } ! 963: /*XXX | tn_list TNAME SM ! 964: * { Pname n = Ncopy($<pn>2); ! 965: * n->n_qualifier = $<pn>1; ! 966: * n->base = PR; ! 967: * $$ = n; ! 968: * } ! 969: */ | tn_list fname SM ! 970: { Pname n = Ncopy($<pn>2); ! 971: if (n->n_oper == TYPE) { ! 972: error('s',"visibilityD for conversion operator"); ! 973: // n->tp = Ptype(n->n_initializer); ! 974: n->tp = Ptype(n->cond); ! 975: n->cond = 0; ! 976: // n->n_initializer = 0; ! 977: n->n_oper = 0; ! 978: sig_name(n); ! 979: } ! 980: n->n_qualifier = $<pn>1; ! 981: n->base = PR; ! 982: $$ = n; ! 983: } ! 984: ; ! 985: ! 986: /************* declarators: returns Pname **********************/ ! 987: /* a ``decl'' is used for function and data declarations, ! 988: and for member declarations ! 989: (it has a name) ! 990: an ``arg_decl'' is used for argument declarations ! 991: (it may or may not have a name) ! 992: an ``cast_decl'' is used for casts ! 993: (it does not have a name) ! 994: a ``new_decl'' is used for type specifiers for the NEW operator ! 995: (it does not have a name, and PtoF and PtoV cannot be expressed) ! 996: */ ! 997: ! 998: fname : ID ! 999: { $$ = $<pn>1; } ! 1000: | COMPL TNAME /* qualified_tname? */ ! 1001: { $$ = Ncopy($<pn>2); ! 1002: $<pn>$->n_oper = DTOR; ! 1003: } ! 1004: | OPERATOR oper ! 1005: { $$ = new name(oper_name($2)); ! 1006: $<pn>$->n_oper = $<t>2; ! 1007: } ! 1008: | OPERATOR c_type ! 1009: { Pname n = $<pn>2; ! 1010: n->string = "_type"; ! 1011: n->n_oper = TYPE; ! 1012: n->cond = Pexpr(n->tp); ! 1013: // n->n_initializer = Pexpr(n->tp); ! 1014: n->tp = 0; ! 1015: $$ = n; ! 1016: } ! 1017: ; ! 1018: ! 1019: oper : PLUS ! 1020: | MINUS ! 1021: | MUL ! 1022: | AND ! 1023: | OR ! 1024: | ER ! 1025: | SHIFTOP ! 1026: | EQUOP ! 1027: | DIVOP ! 1028: | RELOP ! 1029: | ANDAND ! 1030: | OROR ! 1031: | LP RP { $$ = CALL; } ! 1032: | LB RB { $$ = DEREF; } ! 1033: | NOT ! 1034: | COMPL ! 1035: | ICOP ! 1036: | ASOP ! 1037: | ASSIGN ! 1038: | NEW { $$ = NEW; } ! 1039: | DELETE { $$ = DELETE; } ! 1040: | REF { $$ = REF; } ! 1041: | CM { $$ = CM; } ! 1042: | REFMUL { $$ = REFMUL; ! 1043: if ($<t>1 == DOT) error(".* cannot be overloaded"); ! 1044: } ! 1045: ; ! 1046: ! 1047: tn_list : tscope ! 1048: /*XXX*/ { if ( $<pn>1 != sta_name ) { ! 1049: // error('d',"tn_list: tscope: pn1: %s", $<pn>1->string); ! 1050: Ptype t = $<pn>1->tp; ! 1051: while ( t->base == TYPE ) ! 1052: t = Pbase(t)->b_name->tp; ! 1053: Pname n = Pbase(t)->b_name; ! 1054: if (NEXTTOK() == TNAME ! 1055: && strcmp(n->string,yylval.pn->string)==0){ ! 1056: // ctor -- change to ID to avoid ! 1057: // parsing as type spec ! 1058: yychar = ID; ! 1059: yylval.pn = Ncopy(yylval.pn); ! 1060: yylval.pn->n_oper = TNAME; ! 1061: } ! 1062: } ! 1063: $<pn>$ = $<pn>1; ! 1064: } ! 1065: /* YYY | tn_list tscope { $<pn>$ = $<pn>1; } */ ! 1066: | tn_list tscope { error('s', "CNs do not nest, use typedef x::y y_in_x"); }; ! 1067: /*XXX | tn_list ID DOT { error("CNs do not nest"); } */ ! 1068: ; ! 1069: ! 1070: qualified_tname : tn_list TNAME ! 1071: { $<pn>$ = $<pn>2; ! 1072: //xxx qualifier currently ignored... ! 1073: // $<pn>$ = Ncopy( $<pn>2 ); ! 1074: // $<pn>$->n_oper = TNAME; ! 1075: // $<pn>$->n_qualifier = $<pn>1; ! 1076: } ! 1077: | TNAME ! 1078: { $<pn>$ = $<pn>1; ! 1079: // $<pn>$ = Ncopy( $<pn>1 ); ! 1080: // $<pn>$->n_oper = TNAME; ! 1081: } ! 1082: ; ! 1083: ! 1084: fct_attributes : /* empty */ ! 1085: { $$ = 0; } ! 1086: | fct_attributes TYPE ! 1087: { /* const/volatile function */ ! 1088: switch ( $<t>2 ) { ! 1089: case VOLATILE: ! 1090: error('s',"volatile functions"); ! 1091: break; ! 1092: case CONST: ! 1093: $$ = ($1 | 1); ! 1094: break; ! 1095: default: ! 1096: if ( NEXTTOK() != SM ! 1097: && yychar != COLON ! 1098: && yychar != LC ) { ! 1099: la_backup(yychar,yylval); ! 1100: yylval.t = $<t>2; ! 1101: la_backup(TYPE,yylval); ! 1102: yylval.t = SM; ! 1103: yychar = SM; ! 1104: error("syntax error: unexpected%k (did you forget a `;'?)",$<t>2); ! 1105: } else error("FD syntax: unexpected%k",$<t>2); ! 1106: break; ! 1107: } ! 1108: } ! 1109: ; ! 1110: ! 1111: decl : decl arg_list ! 1112: { Freturns($2) = $<pn>1->tp; ! 1113: $<pn>1->tp = $<pt>2; ! 1114: } ! 1115: | decl LP RP fct_attributes ! 1116: { /* function with no argument */ ! 1117: $<pn>1->tp = new fct($<pn>1->tp,0,1); ! 1118: Pfct($<pn>1->tp)->f_const = ($<i>4 & 1); ! 1119: } ! 1120: | qualified_tname arg_list ! 1121: { Pname n = $<pn>1; ! 1122: $$ = Ncopy(n); ! 1123: if (ccl && strcmp(n->string,ccl->string)) n->hide(); ! 1124: $<pn>$->n_oper = TNAME; ! 1125: Freturns($2) = $<pn>$->tp; ! 1126: $<pn>$->tp = $<pt>2; ! 1127: } ! 1128: | decl arg_lp elist RP ! 1129: /* may be class object initializer, ! 1130: class object vector initializer, ! 1131: if not elist will be a CM or an ID ! 1132: */ ! 1133: { ! 1134: $<pn>1->tp = new fct($<pn>1->tp,$<pn>3,1); ! 1135: in_arg_list = 0; ! 1136: end_al($2,0); ! 1137: } ! 1138: | qualified_tname LP MUL ID RP arg_list ! 1139: { ! 1140: Pptr p = new ptr( PTR, 0 ); ! 1141: Ptyp(p) = new basetype(TYPE,$<pn>1); ! 1142: Freturns( $6 ) = Ptype(p); ! 1143: $<pn>4->tp = $<pt>6; ! 1144: $$ = $4; ! 1145: if (DECL_TYPE == -1) DECL_TYPE = 0; ! 1146: } ! 1147: | qualified_tname LP elist RP ! 1148: { $$ = Ncopy($<pn>1); ! 1149: $<pn>$->n_oper = TNAME; ! 1150: $<pn>$->tp = new fct(0,$<pn>3,1); ! 1151: } ! 1152: | qualified_tname LP RP fct_attributes ! 1153: { /* function with no argument */ ! 1154: $$ = Ncopy($<pn>1); ! 1155: $<pn>$->n_oper = TNAME; ! 1156: $<pn>$->tp = new fct(0,0,1); ! 1157: Pfct($<pn>1->tp)->f_const = ($<i>4 & 1); ! 1158: } ! 1159: | qualified_tname LP MEMPTR decl RP arg_list ! 1160: { memptrdcl($<pn>3,$<pn>1,$<pt>6,$<pn>4); ! 1161: $$ = $4; ! 1162: } ! 1163: | fname ! 1164: | ID DOT fname ! 1165: { $$ = Ncopy($<pn>3); ! 1166: $<pn>$->n_qualifier = $1; ! 1167: error(strict_opt?0:'w',"`.' used for qualification; please use `::' (anachronism)"); ! 1168: } ! 1169: | tn_list fname ! 1170: { $$ = $2; ! 1171: if ( $<pn>1 != sta_name ) { ! 1172: set_scope($<pn>1); ! 1173: $<pn>$->n_qualifier = $<pn>1; ! 1174: } ! 1175: } ! 1176: /*XXX*/ | tn_list ID DOT fname ! 1177: { $$ = Ncopy($<pn>4); ! 1178: $<pn>$->n_qualifier = $2; ! 1179: error(ansi_opt?0:'w',"anachronism `.' used for qualification; please use `::'"); ! 1180: if ( $<pn>1 != sta_name ) { ! 1181: set_scope($<pn>1); ! 1182: $<pn>2->n_qualifier = $<pn>1; ! 1183: } ! 1184: } ! 1185: /*XXX | tn_list TNAME ! 1186: * { ! 1187: * if ( $<pn>1 == sta_name ) ! 1188: * error( ":: applied to CN%n", $<pn>2 ); ! 1189: * $$ = Ncopy($<pn>2); ! 1190: * set_scope($<pn>1); ! 1191: * $<pn>$->n_oper = TNAME; ! 1192: * $<pn>$->n_qualifier = $<pn>1; ! 1193: * } ! 1194: */ | ptr decl %prec MUL ! 1195: { Ptyp($1) = $<pn>2->tp; ! 1196: $<pn>2->tp = $<pt>1; ! 1197: $$ = $2; ! 1198: } ! 1199: | ptr qualified_tname %prec MUL ! 1200: { $$ = Ncopy($<pn>2); ! 1201: $<pn>$->n_oper = TNAME; ! 1202: // cannot evaluate at this point: defer until data_dcl ! 1203: if ( in_typedef ) { ! 1204: defer_check = 1; ! 1205: in_tag = $<pn>2; ! 1206: } ! 1207: $<pn>2->hide(); ! 1208: defer_check = 0; ! 1209: $<pn>$->tp = $<pt>1; ! 1210: } ! 1211: | qualified_tname vec %prec LB ! 1212: { $$ = Ncopy($<pn>1); ! 1213: $<pn>$->n_oper = TNAME; ! 1214: if ( in_typedef ) { ! 1215: defer_check = 1; ! 1216: in_tag = $<pn>2; ! 1217: } ! 1218: $<pn>1->hide(); ! 1219: defer_check = 0; ! 1220: $<pn>$->tp = $<pt>2; ! 1221: } ! 1222: | decl vec %prec LB ! 1223: { Vtype($2) = $<pn>1->tp; ! 1224: $<pn>1->tp = $<pt>2; ! 1225: } ! 1226: /* ! 1227: | LP decl RP arg_list ! 1228: { ! 1229: Freturns($4) = $<pn>2->tp; ! 1230: $<pn>2->tp = $<pt>4; ! 1231: $$ = $2; ! 1232: } ! 1233: | LP decl RP vec ! 1234: { Vtype($4) = $<pn>2->tp; ! 1235: $<pn>2->tp = $<pt>4; ! 1236: $$ = $2; ! 1237: } ! 1238: */ ! 1239: | arg_lp decl RP ! 1240: { ! 1241: $$ = $2; ! 1242: in_arg_list = 0; ! 1243: end_al($1,0); ! 1244: } ! 1245: ; ! 1246: ! 1247: arg_decl : ID ! 1248: { $$ = $<pn>1; } ! 1249: | ptr qualified_tname %prec MUL ! 1250: { $$ = Ncopy($<pn>2); ! 1251: $<pn>$->n_oper = TNAME; ! 1252: $<pn>2->hide(); ! 1253: $<pn>$->tp = $<pt>1; ! 1254: } ! 1255: | %prec NO_ID ! 1256: { ! 1257: $$ = new name; ! 1258: NOT_EXPECT_ID(); ! 1259: } ! 1260: | ptr arg_decl %prec MUL ! 1261: { Ptyp($1) = $<pn>2->tp; ! 1262: $<pn>2->tp = (Ptype)$1; ! 1263: $$ = $2; ! 1264: } ! 1265: | arg_decl vec %prec LB ! 1266: { Vtype($2) = $<pn>1->tp; ! 1267: $<pn>1->tp = (Ptype)$2; ! 1268: } ! 1269: | arg_decl arg_list ! 1270: { Freturns($2) = $<pn>1->tp; ! 1271: $<pn>1->tp = (Ptype)$2; ! 1272: } ! 1273: /* ! 1274: | LP arg_decl RP arg_list ! 1275: { Freturns($4) = $<pn>2->tp; ! 1276: $<pn>2->tp = (Ptype)$4; ! 1277: $$ = $2; ! 1278: } ! 1279: | LP arg_decl RP vec ! 1280: { Vtype($4) = $<pn>2->tp; ! 1281: $<pn>2->tp = (Ptype)$4; ! 1282: $$ = $2; ! 1283: } ! 1284: */ ! 1285: | arg_lp arg_decl RP ! 1286: { ! 1287: // error('d', "arg_lp arg_decl rp in_arg_list: %d", in_arg_list ); ! 1288: $$ = $2; ! 1289: in_arg_list = 0; ! 1290: end_al($1,0); ! 1291: } ! 1292: ; ! 1293: ! 1294: new_decl : %prec NO_ID ! 1295: { $$ = new name; } ! 1296: | ptr new_decl %prec MUL ! 1297: { Ptyp($1) = $<pn>2->tp; ! 1298: $<pn>2->tp = (Ptype)$1; ! 1299: $$ = $2; ! 1300: NOT_EXPECT_ID(); ! 1301: } ! 1302: | new_decl vec %prec LB ! 1303: { Vtype($2) = $<pn>1->tp; ! 1304: $<pn>1->tp = (Ptype)$2; ! 1305: } ! 1306: ; ! 1307: ! 1308: cast_decl : %prec NO_ID { $$ = new name; } ! 1309: | ptr cast_decl %prec MUL ! 1310: { Ptyp($1) = $<pn>2->tp; ! 1311: $<pn>2->tp = (Ptype)$1; ! 1312: $$ = $2; ! 1313: NOT_EXPECT_ID(); ! 1314: } ! 1315: | cast_decl vec %prec LB ! 1316: { Vtype($2) = $<pn>1->tp; ! 1317: $<pn>1->tp = (Ptype)$2; ! 1318: } ! 1319: | LP cast_decl RP arg_list ! 1320: { Freturns($4) = $<pn>2->tp; ! 1321: $<pn>2->tp = $<pt>4; ! 1322: $$ = $2; ! 1323: } ! 1324: | LP cast_decl RP vec ! 1325: { Vtype($4) = $<pn>2->tp; ! 1326: $<pn>2->tp = $<pt>4; ! 1327: $$ = $2; ! 1328: } ! 1329: ; ! 1330: ! 1331: c_decl : %prec NO_ID ! 1332: { $$ = new name; } ! 1333: | ptr c_decl %prec MUL ! 1334: { Ptyp($1) = $<pn>2->tp; ! 1335: $<pn>2->tp = (Ptype)$1; ! 1336: $$ = $2; ! 1337: } ! 1338: ; ! 1339: ! 1340: ! 1341: ! 1342: /***************** statements: returns Pstmt *****************/ ! 1343: stmt_list : /* empty */ ! 1344: { ! 1345: $$ = 0; ! 1346: } ! 1347: | stmt_list caselab_stmt ! 1348: { ! 1349: if ($2) ! 1350: if ($1) ! 1351: $<sl>1->add($<ps>2); ! 1352: else { ! 1353: $<sl>$ = new slist($<ps>2); ! 1354: stmt_seen = 1; ! 1355: } ! 1356: } ! 1357: ; ! 1358: caselab_stmt : caselablist statement ! 1359: { ! 1360: $$ = $2; ! 1361: if ($2) stmt_seen = 1; ! 1362: } ! 1363: ; ! 1364: ! 1365: caselablist : /* empty */ ! 1366: { ! 1367: $$ = 0; ! 1368: check_decl(); ! 1369: } ! 1370: ; ! 1371: ! 1372: condition : LP e RP ! 1373: { $$ = $2; ! 1374: /* if ($<pe>$ == dummy) error("empty condition");*/ ! 1375: stmt_seen = 1; ! 1376: } ! 1377: ; ! 1378: ! 1379: block : LC ! 1380: { cd_vec[cdi] = cd; ! 1381: stmt_vec[cdi] = stmt_seen; ! 1382: tn_vec[cdi] = modified_tn; ! 1383: lcl_blk_vec[cdi++] = local_blk; ! 1384: lcl_tn_vec[cdi] = local_tn; ! 1385: local_blk = 0; ! 1386: local_tn = 0; ! 1387: cd = 0; ! 1388: stmt_seen = 0; ! 1389: modified_tn = 0; ! 1390: } ! 1391: stmt_list RC ! 1392: { Pname n = name_unlist(cd); ! 1393: Pstmt ss = stmt_unlist($<sl>3); ! 1394: $$ = new block($<l>1,n,ss,$<l>4); ! 1395: if ( local_tn ) local_restore(); ! 1396: if ( local_blk ) local_name(); ! 1397: if (modified_tn) restore(); ! 1398: cd = cd_vec[--cdi]; ! 1399: stmt_seen = stmt_vec[cdi]; ! 1400: modified_tn = tn_vec[cdi]; ! 1401: local_tn = lcl_tn_vec[cdi]; ! 1402: local_blk = lcl_blk_vec[cdi]; ! 1403: if (cdi < 0) error('i',"block level(%d)",cdi); ! 1404: NOT_EXPECT_ID(); ! 1405: } ! 1406: | LC RC ! 1407: { $$ = new block($<l>1,0,0,$<l>2); NOT_EXPECT_ID();} ! 1408: | LC error RC ! 1409: { $$ = new block($<l>1,0,0,$<l>3); NOT_EXPECT_ID();} ! 1410: ; ! 1411: ! 1412: simple : ee ! 1413: { $$ = new estmt(SM,curloc,$<pe>1,0); } ! 1414: | BREAK ! 1415: { $$ = new stmt(BREAK,$<l>1,0); } ! 1416: | CONTINUE ! 1417: { $$ = new stmt(CONTINUE,$<l>1,0); } ! 1418: | GOTO ID ! 1419: { $$ = new lstmt(GOTO,$<l>1,$<pn>2,0); } ! 1420: | DO { stmt_seen=1; } caselab_stmt WHILE condition ! 1421: { $$ = new estmt(DO,$<l>1,$<pe>5,$<ps>3); } ! 1422: | ASM LP STRING RP ! 1423: { ! 1424: if (stmt_seen) ! 1425: $$ = new estmt(ASM,curloc,(Pexpr)$<s>3,0); ! 1426: else { ! 1427: Pname n = new name(make_name('A')); ! 1428: n->tp = new basetype(ASM,(Pname)$<s>3); ! 1429: if (cd) ! 1430: cd->add_list(n); ! 1431: else ! 1432: cd = new nlist(n); ! 1433: $$ = 0; ! 1434: } ! 1435: } ! 1436: ; ! 1437: ! 1438: sm : { ! 1439: if ( NEXTTOK() != SM ) { ! 1440: error("`;' missing afterS"); ! 1441: la_backup(yychar,yylval); ! 1442: yychar = SM; ! 1443: } ! 1444: } SM ! 1445: ; ! 1446: ! 1447: statement : simple sm ! 1448: | SM ! 1449: { $$ = new estmt(SM,$<l>1,dummy,0); } ! 1450: | RETURN e SM ! 1451: { $$ = new estmt(RETURN,$<l>1,$<pe>2,0); } ! 1452: | TYPE STRING block ! 1453: { ! 1454: error("local linkage specification"); ! 1455: $$ = $<pn>3; ! 1456: } ! 1457: | data_dcl ! 1458: { Pname n = $<pn>1; ! 1459: if (n) ! 1460: if (stmt_seen) { ! 1461: $$ = new block(n->where,n,0); ! 1462: $<ps>$->base = DCL; ! 1463: } ! 1464: else { ! 1465: if (cd) ! 1466: cd->add_list(n); ! 1467: else ! 1468: cd = new nlist(n); ! 1469: $$ = 0; ! 1470: } ! 1471: } ! 1472: | att_fct_def ! 1473: { ! 1474: Pname n = $<pn>1; ! 1475: error(&n->where,"%n's definition is nested (did you forget a ``}''?)",n); ! 1476: if (cd) ! 1477: cd->add_list(n); ! 1478: else ! 1479: cd = new nlist(n); ! 1480: $$ = 0; ! 1481: } ! 1482: | block ! 1483: | IF condition caselab_stmt ! 1484: { $$ = new ifstmt($<l>1,$<pe>2,$<ps>3,0); } ! 1485: | IF condition caselab_stmt ELSE caselab_stmt ! 1486: { $$ = new ifstmt($<l>1,$<pe>2,$<ps>3,$<ps>5); } ! 1487: | WHILE condition caselab_stmt ! 1488: { $$ = new estmt(WHILE,$<l>1,$<pe>2,$<ps>3); } ! 1489: | FOR LP { stmt_seen=1; } caselab_stmt e SM e RP caselab_stmt ! 1490: { $$ = new forstmt($<l>1,$<ps>4,$<pe>5,$<pe>7,$<ps>9); } ! 1491: | SWITCH condition caselab_stmt ! 1492: { $$ = new estmt(SWITCH,$<l>1,$<pe>2,$<ps>3); } ! 1493: | ID COLON { $$ = $1; stmt_seen=1; } caselab_stmt ! 1494: { Pname n = $<pn>3; ! 1495: $$ = new lstmt(LABEL,n->where,n,$<ps>4); ! 1496: } ! 1497: | TNAME COLON { $$ = new name($<pn>1->string); stmt_seen=1; } caselab_stmt ! 1498: { Pname n = $<pn>3; ! 1499: $$ = new lstmt(LABEL,n->where,n,$<ps>4); ! 1500: } ! 1501: | CASE { stmt_seen=1; } e COLON caselab_stmt ! 1502: { if ($<pe>3 == dummy) error("empty case label"); ! 1503: $$ = new estmt(CASE,$<l>1,$<pe>3,$<ps>5); ! 1504: } ! 1505: | DEFAULT COLON { stmt_seen=1; } caselab_stmt ! 1506: { $$ = new stmt(DEFAULT,$<l>1,$<ps>4); } ! 1507: ; ! 1508: ! 1509: ! 1510: ! 1511: /********************* expressions: returns Pexpr **************/ ! 1512: elist : ex_list ! 1513: { Pexpr e = expr_unlist($<el>1); ! 1514: while (e && e->e1==dummy) { ! 1515: register Pexpr ee2 = e->e2; ! 1516: if (ee2) error("EX inEL"); ! 1517: delete e; ! 1518: e = ee2; ! 1519: } ! 1520: $$ = e; ! 1521: } ! 1522: ; ! 1523: ! 1524: ex_list : initializer %prec CM ! 1525: { $<el>$ = new elist(new expr(ELIST,$<pe>1,0)); } ! 1526: | ex_list CM initializer ! 1527: { $<el>1->add(new expr(ELIST,$<pe>3,0)); } ! 1528: ; ! 1529: ! 1530: initializer : e %prec CM ! 1531: | LC elist RC ! 1532: { ! 1533: if ( in_arg_list ) ! 1534: error( "syntax error: IrL not permitted in AL" ); ! 1535: else if ( in_binit_list ) ! 1536: error( "syntax error: IrL not permitted inMIr" ); ! 1537: else ! 1538: init_seen = 1; ! 1539: Pexpr e; ! 1540: if ($2) ! 1541: e = $<pe>2; ! 1542: else ! 1543: e = new expr(ELIST,dummy,0); ! 1544: $$ = new expr(ILIST,e,0); ! 1545: } ! 1546: ; ! 1547: ! 1548: ee : ee ASSIGN ee ! 1549: { bbinop: $$ = new expr($<t>2,$<pe>1,$<pe>3); } ! 1550: | ee PLUS ee { goto bbinop; } ! 1551: | ee MINUS ee { goto bbinop; } ! 1552: | ee MUL ee { goto bbinop; } ! 1553: | ee AND ee { goto bbinop; } ! 1554: | ee OR ee { goto bbinop; } ! 1555: | ee ER ee { goto bbinop; } ! 1556: | ee SHIFTOP ee { goto bbinop; } ! 1557: | ee EQUOP ee { goto bbinop; } ! 1558: | ee DIVOP ee { goto bbinop; } ! 1559: | ee RELOP ee { goto bbinop; } ! 1560: | ee ANDAND ee { goto bbinop; } ! 1561: | ee OROR ee { goto bbinop; } ! 1562: | ee ASOP ee { goto bbinop; } ! 1563: | ee CM ee { goto bbinop; } ! 1564: | ee QUEST ee COLON ee ! 1565: { $$ = new qexpr($<pe>1,$<pe>3,$<pe>5); } ! 1566: | DELETE term ! 1567: { $$ = new expr(DELETE,$<pe>2,0); } ! 1568: | DELETE LB e RB term ! 1569: { ! 1570: if($<pe>3 != dummy) { ! 1571: if ( warning_opt || strict_opt ) ! 1572: error(strict_opt?0:'w',"v in `delete[v]' is redundant; use `delete[] instead (anachronism)"); ! 1573: } ! 1574: $$ = new expr(DELETE,$<pe>5,$<pe>3); ! 1575: } ! 1576: | MEM DELETE term ! 1577: { $$ = new expr(GDELETE,$<pe>3,0); } ! 1578: | MEM DELETE LB e RB term ! 1579: { ! 1580: if($<pe>4 != dummy) { ! 1581: if ( warning_opt || strict_opt ) ! 1582: error(strict_opt?0:'w',"v in `::delete[v]' is redundant; use `::delete[] instead (anachronism)"); ! 1583: } ! 1584: $$ = new expr(DELETE,$<pe>6,$<pe>4); ! 1585: } ! 1586: | term ! 1587: ; ! 1588: ! 1589: e : e ASSIGN e ! 1590: { binop: $$ = new expr($<t>2,$<pe>1,$<pe>3); } ! 1591: | e PLUS e { goto binop; } ! 1592: | e MINUS e { goto binop; } ! 1593: | e MUL e { goto binop; } ! 1594: | e AND e { goto binop; } ! 1595: | e OR e { goto binop; } ! 1596: | e ER e { goto binop; } ! 1597: | e SHIFTOP e { goto binop; } ! 1598: | e EQUOP e { goto binop; } ! 1599: | e DIVOP e { goto binop; } ! 1600: | e RELOP e { goto binop; } ! 1601: | e ANDAND e { goto binop; } ! 1602: | e OROR e { goto binop; } ! 1603: | e ASOP e { goto binop; } ! 1604: | e CM e { goto binop; } ! 1605: | e QUEST e COLON e ! 1606: { $$ = new qexpr($<pe>1,$<pe>3,$<pe>5); } ! 1607: | DELETE term ! 1608: { $$ = new expr(DELETE,$<pe>2,0); } ! 1609: | DELETE LB e RB term ! 1610: { ! 1611: if($<pe>3 != dummy) { ! 1612: if ( warning_opt || strict_opt ) ! 1613: error(strict_opt?0:'w',"v in `delete[v]' is redundant; use `delete[] instead (anachronism)"); ! 1614: } ! 1615: $$ = new expr(DELETE,$<pe>5,$<pe>3); ! 1616: } ! 1617: | MEM DELETE term ! 1618: { $$ = new expr(GDELETE,$<pe>3,0); } ! 1619: | MEM DELETE LB e RB term ! 1620: { ! 1621: if($<pe>4 != dummy) { ! 1622: if ( warning_opt || strict_opt ) ! 1623: error(strict_opt?0:'w',"v in `::delete[v]' is redundant; use `::delete[] instead (anachronism)"); ! 1624: } ! 1625: $$ = new expr(DELETE,$<pe>6,$<pe>4); ! 1626: } ! 1627: | term { ! 1628: init_seen = 0; ! 1629: } ! 1630: | %prec NO_EXPR ! 1631: { $$ = dummy; } ! 1632: ; ! 1633: ! 1634: term : NEW cast_type { goto new1; } ! 1635: | NEW new_type ! 1636: { new1: ! 1637: Ptype t = $<pn>2->tp; ! 1638: $$ = new texpr(NEW,t,0); ! 1639: } ! 1640: | MEM NEW cast_type { goto new3; } ! 1641: | MEM NEW new_type ! 1642: { new3: ! 1643: Ptype t = $<pn>3->tp; ! 1644: $$ = new texpr(GNEW,t,0); ! 1645: } ! 1646: | term ICOP ! 1647: { $$ = new expr($<t>2,$<pe>1,0); } ! 1648: | cast_type term %prec ICOP ! 1649: { $$ = new texpr(CAST,$<pn>1->tp,$<pe>2); } ! 1650: | MUL term ! 1651: { $$ = new expr(DEREF,$<pe>2,0); } ! 1652: | AND term ! 1653: { $$ = new expr(ADDROF,0,$<pe>2); } ! 1654: | MINUS term ! 1655: { $$ = new expr(UMINUS,0,$<pe>2); } ! 1656: | PLUS term ! 1657: { $$ = new expr(UPLUS,0,$<pe>2); } ! 1658: | NOT term ! 1659: { $$ = new expr(NOT,0,$<pe>2); } ! 1660: | COMPL term ! 1661: { $$ = new expr(COMPL,0,$<pe>2); } ! 1662: | ICOP term ! 1663: { $$ = new expr($<t>1,0,$<pe>2); } ! 1664: | SIZEOF term ! 1665: { ! 1666: $$ = new texpr(SIZEOF,0,$<pe>2); ! 1667: in_sizeof = 0; ! 1668: } ! 1669: | SIZEOF cast_type %prec SIZEOF ! 1670: { ! 1671: $$ = new texpr(SIZEOF,$<pn>2->tp,0); ! 1672: in_sizeof = 0; ! 1673: } ! 1674: | term LB e RB ! 1675: { $$ = new expr(DEREF,$<pe>1,$<pe>3); } ! 1676: | term REF prim ! 1677: { $$ = new ref(REF,$<pe>1,$<pn>3); } ! 1678: | term REFMUL term ! 1679: { $$ = new expr($<t>2,$<pe>1,$<pe>3); } ! 1680: | term REF qualified_tname ! 1681: { $$ = new ref(REF,$<pe>1,Ncopy($<pn>3)); } ! 1682: | term DOT prim ! 1683: { $$ = new ref(DOT,$<pe>1,$<pn>3); } ! 1684: | term DOT qualified_tname ! 1685: { $$ = new ref(DOT,$<pe>1,Ncopy($<pn>3)); } ! 1686: | prim ! 1687: | term_elist ! 1688: { ! 1689: if ( init_seen ) ! 1690: error( "syntax error:IrL illegal within ()"); ! 1691: } ! 1692: ! 1693: | term_lp e RP ! 1694: { ! 1695: if ( $2 == dummy ) ! 1696: error("syntax error: nullE"); ! 1697: $$ = $2; ! 1698: } ! 1699: | ZERO ! 1700: { $$ = zero; } ! 1701: | ICON ! 1702: { $$ = new expr(ICON,0,0); ! 1703: $<pe>$->string = $<s>1; ! 1704: } ! 1705: | FCON ! 1706: { $$ = new expr(FCON,0,0); ! 1707: $<pe>$->string = $<s>1; ! 1708: } ! 1709: | STRING ! 1710: { $$ = new expr(STRING,0,0); ! 1711: $<pe>$->string = $<s>1; ! 1712: } ! 1713: | CCON ! 1714: { $$ = new expr(CCON,0,0); ! 1715: $<pe>$->string = $<s>1; ! 1716: } ! 1717: | THIS ! 1718: { $$ = new expr(THIS,0,0); } ! 1719: ; ! 1720: ! 1721: term_elist : TYPE LP elist RP ! 1722: { $$ = new texpr(VALUE,tok_to_type($<t>1),$<pe>3); } ! 1723: | qualified_tname LP elist RP ! 1724: { $$ = new texpr(VALUE,$<pn>1->tp,$<pe>3); } ! 1725: | NEW term_lp elist RP cast_type { goto new2; } ! 1726: | NEW term_lp elist RP new_type /* allow separate allocation */ ! 1727: { new2: ! 1728: Ptype t = $<pn>5->tp; ! 1729: $$=new texpr(NEW,t,0); ! 1730: $<pe>$->e2 = $<pe>3; ! 1731: } ! 1732: | MEM NEW term_lp elist RP cast_type { goto new4; } ! 1733: | MEM NEW term_lp elist RP new_type /* allow separate allocation */ ! 1734: { new4: ! 1735: Ptype t = $<pn>6->tp; ! 1736: $$ = new texpr(GNEW,t,0); ! 1737: $<pe>$->e2 = $<pe>4; ! 1738: } ! 1739: | term LP elist RP ! 1740: { ! 1741: Pexpr ee = $<pe>3; ! 1742: Pexpr e = $<pe>1; ! 1743: if (e->base==NEW || e->base==GNEW) ! 1744: e->e1 = ee; ! 1745: else ! 1746: $$ = new call(e,ee); ! 1747: } ! 1748: ! 1749: ; ! 1750: tscope : TSCOPE ! 1751: { ! 1752: $<pn>$ = $<pn>1; ! 1753: curr_scope = $<pn>1; ! 1754: } ! 1755: | MEM ! 1756: { $<pn>$ = sta_name; } ! 1757: ; ! 1758: ! 1759: ! 1760: prim : ID ! 1761: { $$ = $<pn>1; } ! 1762: /*XXX*/ | tn_list ID ! 1763: { $$ = Ncopy($<pn>2); ! 1764: $<pn>$->n_qualifier = $<pn>1; ! 1765: } ! 1766: | OPERATOR oper ! 1767: { $$ = new name(oper_name($2)); ! 1768: $<pn>$->n_oper = $<t>2; ! 1769: } ! 1770: | tn_list OPERATOR oper ! 1771: { $$ = new name(oper_name($3)); ! 1772: $<pn>$->n_oper = $<t>3; ! 1773: $<pn>$->n_qualifier = $<pn>1; ! 1774: } ! 1775: | OPERATOR c_type ! 1776: { $$ = $2; ! 1777: sig_name($<pn>$); ! 1778: } ! 1779: | tn_list OPERATOR c_type ! 1780: { $$ = $3; ! 1781: sig_name($<pn>$); ! 1782: $<pn>$->n_qualifier = $<pn>1; ! 1783: } ! 1784: | tn_list COMPL tag /* allow explicit call of destructor */ ! 1785: { ! 1786: if (strcmp($<pn>1->string,$<pn>3->string)) error("syntax error: inconsistent destructor notation"); ! 1787: $$ = new name(oper_name(DTOR)); ! 1788: $<pn>$->n_oper = DTOR; ! 1789: $<pn>$->n_qualifier = $<pn>1; ! 1790: } ! 1791: ; ! 1792: ! 1793: ! 1794: ! 1795: /****************** abstract types (return type Pname) *************/ ! 1796: cast_type : term_lp type cast_decl RP ! 1797: { $$ = Ncast($2,$<pn>3); } ! 1798: ; ! 1799: ! 1800: term_lp : LP { check_cast(); } ! 1801: ; ! 1802: ! 1803: c_tp : TYPE ! 1804: { ! 1805: TOK t = $<t>1; ! 1806: ! 1807: switch (t) { ! 1808: case FRIEND: ! 1809: case OVERLOAD: ! 1810: case REGISTER: ! 1811: case STATIC: ! 1812: case EXTERN: ! 1813: case AUTO: ! 1814: case VIRTUAL: ! 1815: error("%k in operatorT",t); ! 1816: t = INT; ! 1817: ! 1818: } ! 1819: ! 1820: $$ = new basetype(t,0); ! 1821: ! 1822: } ! 1823: | qualified_tname { $$ = new basetype(TYPE,$<pn>1); } ! 1824: | c_tp TYPE ! 1825: { ! 1826: if ( DECL_TYPE != -1 ) ! 1827: $$ = $<pb>1->type_adj($<t>2); ! 1828: DECL_TYPE = 0; ! 1829: } ! 1830: | c_tp qualified_tname ! 1831: { ! 1832: if ( DECL_TYPE != -1 ) ! 1833: $$ = $<pb>1->name_adj($<pn>2); ! 1834: DECL_TYPE = 0; ! 1835: } ! 1836: ; ! 1837: ! 1838: c_type : c_tp c_decl { $$ = Ncast($1,$<pn>2); } ! 1839: ; ! 1840: ! 1841: new_type : type new_decl { $$ = Ncast($1,$<pn>2); }; ! 1842: ! 1843: arg_type : type arg_decl ! 1844: { $$ = Ndata($1,$<pn>2); } ! 1845: | type arg_decl ASSIGN initializer ! 1846: { $$ = Ndata($1,$<pn>2); ! 1847: $<pn>$->n_initializer = $<pe>4; ! 1848: } ! 1849: ; ! 1850: ! 1851: arg_lp : LP ! 1852: { ! 1853: check_decl(); ! 1854: in_arg_list=1; ! 1855: $$ = modified_tn; ! 1856: modified_tn = 0; ! 1857: } ! 1858: ; ! 1859: ! 1860: arg_list : arg_lp arg_type_list ellipsis_opt RP fct_attributes ! 1861: { ! 1862: $$ = new fct(0,name_unlist($<nl>2),$<t>3); ! 1863: if ( NEXTTOK() != COLON ) in_arg_list=0; ! 1864: //in_arg_list=0; ! 1865: Pfct($<pt>$)->f_const = ($<i>5 & 1); ! 1866: if ( parsing_class_members ! 1867: || (NEXTTOK()!=LC && yychar!=COLON)) ! 1868: end_al($1,1); ! 1869: else ! 1870: end_al($1,0); ! 1871: } ! 1872: ; ! 1873: ! 1874: arg_type_list : arg_type_list CM at ! 1875: { ! 1876: if ($3) ! 1877: if ($1) ! 1878: $<nl>1->add($<pn>3); ! 1879: else { ! 1880: error("AD syntax"); ! 1881: $<nl>$ = new nlist($<pn>3); ! 1882: } ! 1883: else ! 1884: error("AD syntax"); ! 1885: } ! 1886: | at %prec CM ! 1887: { ! 1888: if ($1) $<nl>$ = new nlist($<pn>1); ! 1889: } ! 1890: ; ! 1891: ! 1892: at : arg_type ! 1893: | %prec EMPTY { $$ = 0; } ! 1894: ; ! 1895: ! 1896: ellipsis_opt : /* empty */ ! 1897: { $$ = 1; } ! 1898: | ELLIPSIS ! 1899: { $$ = ELLIPSIS; } ! 1900: | CM ELLIPSIS ! 1901: { $$ = ELLIPSIS; } ! 1902: ; ! 1903: ! 1904: ptr : MUL %prec NO_ID ! 1905: { ! 1906: $$ = new ptr(PTR,0); ! 1907: EXPECT_ID(); ! 1908: } ! 1909: | AND %prec NO_ID ! 1910: { ! 1911: $$ = new ptr(RPTR,0); ! 1912: EXPECT_ID(); ! 1913: } ! 1914: | MUL TYPE %prec NO_ID ! 1915: { $$ = doptr(PTR,$<t>2); } ! 1916: | ptr TYPE %prec NO_ID ! 1917: { ! 1918: switch ( $<t>2 ) { ! 1919: case CONST: ! 1920: $<pp>1->rdo = 1; break; ! 1921: case VOLATILE: ! 1922: error('w',"\"volatile\" not implemented (ignored)"); ! 1923: break; ! 1924: default: ! 1925: error( "syntax error: *%k", $<t>2 ); ! 1926: } ! 1927: $$ = $<pp>1; ! 1928: } ! 1929: | AND TYPE %prec NO_ID ! 1930: { $$ = doptr(RPTR,$<t>2); } ! 1931: | MEMPTR %prec NO_ID ! 1932: { ! 1933: $$ = new ptr(PTR,0); ! 1934: $<pp>$->memof = Pclass(Pbase($<pn>1->tp)->b_name->tp); ! 1935: EXPECT_ID(); ! 1936: } ! 1937: | MEMPTR TYPE %prec NO_ID ! 1938: { $$ = doptr(PTR,$<t>2); ! 1939: $<pp>$->memof = Pclass(Pbase($<pn>1->tp)->b_name->tp); ! 1940: } ! 1941: ; ! 1942: ! 1943: vec : LB e RB { $$ = new vec(0,$<pe>2!=dummy?$<pe>2:0 ); } ! 1944: | NOT %prec LB { $$ = new vec(0,0); } ! 1945: ; ! 1946: ! 1947: %% ! 1948: ! 1949: static void ! 1950: check_tag() ! 1951: /* ! 1952: Allow the case of inline/virtual/overload as ! 1953: modifiers of return type of form struct/class/union x foo() ! 1954: SM, COLON, LC ==> real class declaration, not return type ! 1955: */ ! 1956: { ! 1957: switch ( NEXTTOK() ) { ! 1958: case SM: case COLON: case LC: ! 1959: declTag = 1; ! 1960: break; ! 1961: default: ! 1962: declTag = 0; ! 1963: break; ! 1964: } ! 1965: } ! 1966: ! 1967: static void ! 1968: end_al( Plist mtn, int rst ) ! 1969: // unhide type names hidden by arg names ! 1970: // mtn == saved modified_tn ! 1971: { ! 1972: if ( rst == 0 ) { ! 1973: // not really an arg list, or we are entering a function def ! 1974: // merge modified_tn and don't restore ! 1975: if ( modified_tn == 0 ) modified_tn = mtn; ! 1976: else { ! 1977: for ( Plist l = modified_tn; l->l; l = l->l ) ; ! 1978: l->l = mtn; ! 1979: } ! 1980: } else { ! 1981: restore(); ! 1982: modified_tn = mtn; ! 1983: } ! 1984: } ! 1985: static void ! 1986: arg_redec( Pname fn ) ! 1987: { ! 1988: if ( fn==0 || fn->tp->base != FCT ) ! 1989: error('i',"bad inline rewrite!"); ! 1990: Pname al = Pfct(fn->tp)->argtype; ! 1991: Pname n = 0; ! 1992: for ( ; al; al = al->n_list ) { ! 1993: DB( if(Ydebug>=1)error('d',"arg_redec: %n %d",al,al->lex_level); ); ! 1994: // nested function args should have lex_level >= 1 ! 1995: if ( al->lex_level==1 && (n=ktbl->look(al->string,0)) ) ! 1996: n->hide(); ! 1997: else if ( al->lex_level>1 && (n=ktbl->look(al->string,LOCAL)) ) ! 1998: n->hide(); ! 1999: DB( if(Ydebug>=1)error('d'," %n",n); ); ! 2000: } ! 2001: } ! 2002: ! 2003:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.