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