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