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