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