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