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