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