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