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