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