Annotation of src/usr.bin/xlint/lint1/cgram.y, Revision 1.4
1.2 cgd 1: %{
1.4 ! jpo 2: /* $NetBSD: cgram.y,v 1.3 1995/10/02 17:08:31 jpo Exp $ */
1.2 cgd 3:
1.1 cgd 4: /*
5: * Copyright (c) 1994, 1995 Jochen Pohl
6: * All Rights Reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: * 3. All advertising materials mentioning features or use of this software
17: * must display the following acknowledgement:
18: * This product includes software developed by Jochen Pohl for
19: * The NetBSD Project.
20: * 4. The name of the author may not be used to endorse or promote products
21: * derived from this software without specific prior written permission.
22: *
23: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33: */
34:
35: #ifndef lint
1.4 ! jpo 36: static char rcsid[] = "$NetBSD: cgram.y,v 1.3 1995/10/02 17:08:31 jpo Exp $";
1.1 cgd 37: #endif
38:
39: #include <stdlib.h>
40: #include <limits.h>
41:
42: #include "lint1.h"
43:
44: /*
45: * Contains the level of current declaration. 0 is extern.
46: * Used for symbol table entries.
47: */
48: int blklev;
49:
50: /*
51: * level for memory allocation. Normaly the same as blklev.
52: * An exeption is the declaration of arguments in prototypes. Memory
53: * for these can't be freed after the declaration, but symbols must
54: * be removed from the symbol table after the declaration.
55: */
56: int mblklev;
57:
58: static int toicon __P((tnode_t *));
59: static void idecl __P((sym_t *, int));
60:
61: %}
62:
63: %union {
64: int y_int;
65: val_t *y_val;
66: sbuf_t *y_sb;
67: sym_t *y_sym;
68: op_t y_op;
69: scl_t y_scl;
70: tspec_t y_tspec;
71: tqual_t y_tqual;
72: type_t *y_type;
73: tnode_t *y_tnode;
74: strg_t *y_strg;
75: pqinf_t *y_pqinf;
76: };
77:
78: %token T_LBRACE T_RBRACE T_LBRACK T_RBRACK T_LPARN T_RPARN
79: %token <y_op> T_STROP
80: %token <y_op> T_UNOP
81: %token <y_op> T_INCDEC
82: %token T_SIZEOF
83: %token <y_op> T_MULT
84: %token <y_op> T_DIVOP
85: %token <y_op> T_ADDOP
86: %token <y_op> T_SHFTOP
87: %token <y_op> T_RELOP
88: %token <y_op> T_EQOP
89: %token <y_op> T_AND
90: %token <y_op> T_XOR
91: %token <y_op> T_OR
92: %token <y_op> T_LOGAND
93: %token <y_op> T_LOGOR
94: %token T_QUEST
95: %token T_COLON
96: %token <y_op> T_ASSIGN
97: %token <y_op> T_OPASS
98: %token T_COMMA
99: %token T_SEMI
100: %token T_ELLIPSE
101:
102: /* storage classes (extern, static, auto, register and typedef) */
103: %token <y_scl> T_SCLASS
104:
105: /* types (char, int, short, long, unsigned, signed, float, double, void) */
106: %token <y_tspec> T_TYPE
107:
108: /* qualifiers (const, volatile) */
109: %token <y_tqual> T_QUAL
110:
111: /* struct or union */
112: %token <y_tspec> T_SOU
113:
114: /* enum */
115: %token T_ENUM
116:
117: /* remaining keywords */
118: %token T_CASE
119: %token T_DEFAULT
120: %token T_IF
121: %token T_ELSE
122: %token T_SWITCH
123: %token T_DO
124: %token T_WHILE
125: %token T_FOR
126: %token T_GOTO
127: %token T_CONTINUE
128: %token T_BREAK
129: %token T_RETURN
130:
131: %left T_COMMA
132: %right T_ASSIGN T_OPASS
133: %right T_QUEST T_COLON
134: %left T_LOGOR
135: %left T_LOGAND
136: %left T_OR
137: %left T_XOR
138: %left T_AND
139: %left T_EQOP
140: %left T_RELOP
141: %left T_SHFTOP
142: %left T_ADDOP
143: %left T_MULT T_DIVOP
144: %right T_UNOP T_INCDEC T_SIZEOF
145: %left T_LPARN T_LBRACK T_STROP
146:
147: %token <y_sb> T_NAME
148: %token <y_sb> T_TYPENAME
149: %token <y_val> T_CON
150: %token <y_strg> T_STRING
151:
152: %type <y_sym> func_decl
153: %type <y_sym> notype_decl
154: %type <y_sym> type_decl
155: %type <y_type> typespec
156: %type <y_type> clrtyp_typespec
157: %type <y_type> notype_typespec
158: %type <y_type> struct_spec
159: %type <y_type> enum_spec
160: %type <y_sym> struct_tag
161: %type <y_sym> enum_tag
162: %type <y_tspec> struct
163: %type <y_sym> struct_declaration
164: %type <y_sb> identifier
165: %type <y_sym> member_declaration_list_with_rbrace
166: %type <y_sym> member_declaration_list
167: %type <y_sym> member_declaration
168: %type <y_sym> notype_member_decls
169: %type <y_sym> type_member_decls
170: %type <y_sym> notype_member_decl
171: %type <y_sym> type_member_decl
172: %type <y_tnode> constant
173: %type <y_sym> enum_declaration
174: %type <y_sym> enums_with_opt_comma
175: %type <y_sym> enums
176: %type <y_sym> enumerator
177: %type <y_sym> ename
178: %type <y_sym> notype_direct_decl
179: %type <y_sym> type_direct_decl
180: %type <y_pqinf> pointer
181: %type <y_pqinf> asterisk
182: %type <y_sym> param_decl
183: %type <y_sym> param_list
184: %type <y_sym> abs_decl_param_list
185: %type <y_sym> direct_param_decl
186: %type <y_sym> notype_param_decl
187: %type <y_sym> direct_notype_param_decl
188: %type <y_pqinf> type_qualifier_list
189: %type <y_pqinf> type_qualifier
190: %type <y_sym> identifier_list
191: %type <y_sym> abs_decl
192: %type <y_sym> direct_abs_decl
193: %type <y_sym> vararg_parameter_type_list
194: %type <y_sym> parameter_type_list
195: %type <y_sym> parameter_declaration
196: %type <y_tnode> expr
197: %type <y_tnode> term
198: %type <y_tnode> func_arg_list
199: %type <y_op> point_or_arrow
200: %type <y_type> type_name
201: %type <y_sym> abstract_declaration
202: %type <y_tnode> do_while_expr
203: %type <y_tnode> opt_expr
204: %type <y_strg> string
205: %type <y_strg> string2
206:
207:
208: %%
209:
210: program:
211: /* empty */ {
212: if (sflag) {
213: /* empty translation unit */
214: error(272);
215: } else if (!tflag) {
216: /* empty translation unit */
217: warning(272);
218: }
219: }
220: | translation_unit
221: ;
222:
223: translation_unit:
224: ext_decl
225: | translation_unit ext_decl
226: ;
227:
228: ext_decl:
229: func_def {
230: glclrlc(0);
231: }
232: | data_def {
233: glclrlc(0);
234: }
235: ;
236:
237: data_def:
238: T_SEMI {
239: if (sflag) {
240: /* syntax error: empty declaration */
241: error(0);
242: } else if (!tflag) {
243: /* syntax error: empty declaration */
244: warning(0);
245: }
246: }
247: | clrtyp deftyp notype_init_decls T_SEMI {
248: if (sflag) {
249: /* old style declaration; add "int" */
250: error(1);
251: } else if (!tflag) {
252: /* old style declaration; add "int" */
253: warning(1);
254: }
255: }
256: | declmods deftyp T_SEMI {
1.3 jpo 257: if (dcs->d_scl == TYPEDEF) {
1.1 cgd 258: /* typedef declares no type name */
259: warning(72);
260: } else {
261: /* empty declaration */
262: warning(2);
263: }
264: }
265: | declmods deftyp notype_init_decls T_SEMI
266: | declspecs deftyp T_SEMI {
1.3 jpo 267: if (dcs->d_scl == TYPEDEF) {
1.1 cgd 268: /* typedef declares no type name */
269: warning(72);
1.3 jpo 270: } else if (!dcs->d_nedecl) {
1.1 cgd 271: /* empty declaration */
272: warning(2);
273: }
274: }
275: | declspecs deftyp type_init_decls T_SEMI
276: | error T_SEMI {
277: globclup();
278: }
279: | error T_RBRACE {
280: globclup();
281: }
282: ;
283:
284: func_def:
285: func_decl {
286: if ($1->s_type->t_tspec != FUNC) {
287: /* syntax error */
288: error(249);
289: YYERROR;
290: }
291: if ($1->s_type->t_typedef) {
292: /* ()-less function definition */
293: error(64);
294: YYERROR;
295: }
296: funcdef($1);
297: blklev++;
298: pushdecl(ARG);
299: } opt_arg_declaration_list {
300: popdecl();
301: blklev--;
302: cluparg();
303: pushctrl(0);
304: } comp_stmnt {
305: funcend();
306: popctrl(0);
307: }
308: ;
309:
310: func_decl:
311: clrtyp deftyp notype_decl {
312: $$ = $3;
313: }
314: | declmods deftyp notype_decl {
315: $$ = $3;
316: }
317: | declspecs deftyp type_decl {
318: $$ = $3;
319: }
320: ;
321:
322: opt_arg_declaration_list:
323: /* empty */
324: | arg_declaration_list
325: ;
326:
327: arg_declaration_list:
328: arg_declaration
329: | arg_declaration_list arg_declaration
330: /* XXX or better "arg_declaration error" ? */
331: | error
332: ;
333:
334: /*
335: * "arg_declaration" is separated from "declaration" because it
336: * needs other error handling.
337: */
338:
339: arg_declaration:
340: declmods deftyp T_SEMI {
341: /* empty declaration */
342: warning(2);
343: }
344: | declmods deftyp notype_init_decls T_SEMI
345: | declspecs deftyp T_SEMI {
1.3 jpo 346: if (!dcs->d_nedecl) {
1.1 cgd 347: /* empty declaration */
348: warning(2);
349: } else {
1.3 jpo 350: tspec_t ts = dcs->d_type->t_tspec;
1.1 cgd 351: /* %s declared in argument declaration list */
352: warning(3, ts == STRUCT ? "struct" :
353: (ts == UNION ? "union" : "enum"));
354: }
355: }
356: | declspecs deftyp type_init_decls T_SEMI {
1.3 jpo 357: if (dcs->d_nedecl) {
358: tspec_t ts = dcs->d_type->t_tspec;
1.1 cgd 359: /* %s declared in argument declaration list */
360: warning(3, ts == STRUCT ? "struct" :
361: (ts == UNION ? "union" : "enum"));
362: }
363: }
364: | declmods error
365: | declspecs error
366: ;
367:
368: declaration:
369: declmods deftyp T_SEMI {
1.3 jpo 370: if (dcs->d_scl == TYPEDEF) {
1.1 cgd 371: /* typedef declares no type name */
372: warning(72);
373: } else {
374: /* empty declaration */
375: warning(2);
376: }
377: }
378: | declmods deftyp notype_init_decls T_SEMI
379: | declspecs deftyp T_SEMI {
1.3 jpo 380: if (dcs->d_scl == TYPEDEF) {
1.1 cgd 381: /* typedef declares no type name */
382: warning(72);
1.3 jpo 383: } else if (!dcs->d_nedecl) {
1.1 cgd 384: /* empty declaration */
385: warning(2);
386: }
387: }
388: | declspecs deftyp type_init_decls T_SEMI
389: | error T_SEMI
390: ;
391:
392: clrtyp:
393: {
394: clrtyp();
395: }
396: ;
397:
398: deftyp:
399: /* empty */ {
400: deftyp();
401: }
402: ;
403:
404: declspecs:
405: clrtyp_typespec {
406: addtype($1);
407: }
408: | declmods typespec {
409: addtype($2);
410: }
411: | declspecs declmod
412: | declspecs notype_typespec {
413: addtype($2);
414: }
415: ;
416:
417: declmods:
418: clrtyp T_QUAL {
419: addqual($2);
420: }
421: | clrtyp T_SCLASS {
422: addscl($2);
423: }
424: | declmods declmod
425: ;
426:
427: declmod:
428: T_QUAL {
429: addqual($1);
430: }
431: | T_SCLASS {
432: addscl($1);
433: }
434: ;
435:
436: clrtyp_typespec:
437: clrtyp notype_typespec {
438: $$ = $2;
439: }
440: | T_TYPENAME clrtyp {
441: $$ = getsym($1)->s_type;
442: }
443: ;
444:
445: typespec:
446: notype_typespec {
447: $$ = $1;
448: }
449: | T_TYPENAME {
450: $$ = getsym($1)->s_type;
451: }
452: ;
453:
454: notype_typespec:
455: T_TYPE {
456: $$ = gettyp($1);
457: }
458: | struct_spec {
459: popdecl();
460: $$ = $1;
461: }
462: | enum_spec {
463: popdecl();
464: $$ = $1;
465: }
466: ;
467:
468: struct_spec:
469: struct struct_tag {
470: /*
471: * STDC requires that "struct a;" always introduces
472: * a new tag if "a" is not declared at current level
473: *
474: * yychar is valid because otherwise the parse would
475: * not been able to deceide if he must shift or reduce
476: */
477: $$ = mktag($2, $1, 0, yychar == T_SEMI);
478: }
479: | struct struct_tag {
1.3 jpo 480: dcs->d_tagtyp = mktag($2, $1, 1, 0);
1.1 cgd 481: } struct_declaration {
1.3 jpo 482: $$ = compltag(dcs->d_tagtyp, $4);
1.1 cgd 483: }
484: | struct {
1.3 jpo 485: dcs->d_tagtyp = mktag(NULL, $1, 1, 0);
1.1 cgd 486: } struct_declaration {
1.3 jpo 487: $$ = compltag(dcs->d_tagtyp, $3);
1.1 cgd 488: }
489: | struct error {
490: symtyp = FVFT;
491: $$ = gettyp(INT);
492: }
493: ;
494:
495: struct:
496: T_SOU {
497: symtyp = FTAG;
498: pushdecl($1 == STRUCT ? MOS : MOU);
1.3 jpo 499: dcs->d_offset = 0;
500: dcs->d_stralign = CHAR_BIT;
1.1 cgd 501: $$ = $1;
502: }
503: ;
504:
505: struct_tag:
506: identifier {
507: $$ = getsym($1);
508: }
509: ;
510:
511: struct_declaration:
512: struct_decl_lbrace member_declaration_list_with_rbrace {
513: $$ = $2;
514: }
515: ;
516:
517: struct_decl_lbrace:
518: T_LBRACE {
519: symtyp = FVFT;
520: }
521: ;
522:
523: member_declaration_list_with_rbrace:
524: member_declaration_list T_SEMI T_RBRACE {
525: $$ = $1;
526: }
527: | member_declaration_list T_RBRACE {
528: if (sflag) {
529: /* syntax req. ";" after last struct/union member */
530: error(66);
531: } else {
532: /* syntax req. ";" after last struct/union member */
533: warning(66);
534: }
535: $$ = $1;
536: }
537: | T_RBRACE {
538: $$ = NULL;
539: }
540: ;
541:
542: member_declaration_list:
543: member_declaration {
544: $$ = $1;
545: }
546: | member_declaration_list T_SEMI member_declaration {
547: $$ = lnklst($1, $3);
548: }
549: ;
550:
551: member_declaration:
552: noclass_declmods deftyp {
553: /* too late, i know, but getsym() compensates it */
554: symtyp = FMOS;
555: } notype_member_decls {
556: symtyp = FVFT;
557: $$ = $4;
558: }
559: | noclass_declspecs deftyp {
560: symtyp = FMOS;
561: } type_member_decls {
562: symtyp = FVFT;
563: $$ = $4;
564: }
565: | noclass_declmods deftyp {
566: /* struct or union member must be named */
567: warning(49);
568: $$ = NULL;
569: }
570: | noclass_declspecs deftyp {
571: /* struct or union member must be named */
572: warning(49);
573: $$ = NULL;
574: }
575: | error {
576: symtyp = FVFT;
577: $$ = NULL;
578: }
579: ;
580:
581: noclass_declspecs:
582: clrtyp_typespec {
583: addtype($1);
584: }
585: | noclass_declmods typespec {
586: addtype($2);
587: }
588: | noclass_declspecs T_QUAL {
589: addqual($2);
590: }
591: | noclass_declspecs notype_typespec {
592: addtype($2);
593: }
594: ;
595:
596: noclass_declmods:
597: clrtyp T_QUAL {
598: addqual($2);
599: }
600: | noclass_declmods T_QUAL {
601: addqual($2);
602: }
603: ;
604:
605: notype_member_decls:
606: notype_member_decl {
607: $$ = decl1str($1);
608: }
609: | notype_member_decls {
610: symtyp = FMOS;
611: } T_COMMA type_member_decl {
612: $$ = lnklst($1, decl1str($4));
613: }
614: ;
615:
616: type_member_decls:
617: type_member_decl {
618: $$ = decl1str($1);
619: }
620: | type_member_decls {
621: symtyp = FMOS;
622: } T_COMMA type_member_decl {
623: $$ = lnklst($1, decl1str($4));
624: }
625: ;
626:
627: notype_member_decl:
628: notype_decl {
629: $$ = $1;
630: }
631: | notype_decl T_COLON constant {
632: $$ = bitfield($1, toicon($3));
633: }
634: | {
635: symtyp = FVFT;
636: } T_COLON constant {
637: $$ = bitfield(NULL, toicon($3));
638: }
639: ;
640:
641: type_member_decl:
642: type_decl {
643: $$ = $1;
644: }
645: | type_decl T_COLON constant {
646: $$ = bitfield($1, toicon($3));
647: }
648: | {
649: symtyp = FVFT;
650: } T_COLON constant {
651: $$ = bitfield(NULL, toicon($3));
652: }
653: ;
654:
655: enum_spec:
656: enum enum_tag {
657: $$ = mktag($2, ENUM, 0, 0);
658: }
659: | enum enum_tag {
1.3 jpo 660: dcs->d_tagtyp = mktag($2, ENUM, 1, 0);
1.1 cgd 661: } enum_declaration {
1.3 jpo 662: $$ = compltag(dcs->d_tagtyp, $4);
1.1 cgd 663: }
664: | enum {
1.3 jpo 665: dcs->d_tagtyp = mktag(NULL, ENUM, 1, 0);
1.1 cgd 666: } enum_declaration {
1.3 jpo 667: $$ = compltag(dcs->d_tagtyp, $3);
1.1 cgd 668: }
669: | enum error {
670: symtyp = FVFT;
671: $$ = gettyp(INT);
672: }
673: ;
674:
675: enum:
676: T_ENUM {
677: symtyp = FTAG;
678: pushdecl(ENUMCON);
679: }
680: ;
681:
682: enum_tag:
683: identifier {
684: $$ = getsym($1);
685: }
686: ;
687:
688: enum_declaration:
689: enum_decl_lbrace enums_with_opt_comma T_RBRACE {
690: $$ = $2;
691: }
692: ;
693:
694: enum_decl_lbrace:
695: T_LBRACE {
696: symtyp = FVFT;
697: enumval = 0;
698: }
699: ;
700:
701: enums_with_opt_comma:
702: enums {
703: $$ = $1;
704: }
705: | enums T_COMMA {
706: if (sflag) {
707: /* trailing "," prohibited in enum declaration */
708: error(54);
709: } else {
710: /* trailing "," prohibited in enum declaration */
711: warning(54);
712: }
713: $$ = $1;
714: }
715: ;
716:
717: enums:
718: enumerator {
719: $$ = $1;
720: }
721: | enums T_COMMA enumerator {
722: $$ = lnklst($1, $3);
723: }
724: | error {
725: $$ = NULL;
726: }
727: ;
728:
729: enumerator:
730: ename {
731: $$ = ename($1, enumval, 1);
732: }
733: | ename T_ASSIGN constant {
734: $$ = ename($1, toicon($3), 0);
735: }
736: ;
737:
738: ename:
739: identifier {
740: $$ = getsym($1);
741: }
742: ;
743:
744:
745: notype_init_decls:
746: notype_init_decl
747: | notype_init_decls T_COMMA type_init_decl
748: ;
749:
750: type_init_decls:
751: type_init_decl
752: | type_init_decls T_COMMA type_init_decl
753: ;
754:
755: notype_init_decl:
756: notype_decl {
757: idecl($1, 0);
758: chksz($1);
759: }
760: | notype_decl {
761: idecl($1, 1);
762: } T_ASSIGN initializer {
1.4 ! jpo 763: chksz($1);
1.1 cgd 764: }
765: ;
766:
767: type_init_decl:
768: type_decl {
769: idecl($1, 0);
770: chksz($1);
771: }
772: | type_decl {
773: idecl($1, 1);
774: } T_ASSIGN initializer {
1.4 ! jpo 775: chksz($1);
1.1 cgd 776: }
777: ;
778:
779: notype_decl:
780: notype_direct_decl {
781: $$ = $1;
782: }
783: | pointer notype_direct_decl {
784: $$ = addptr($2, $1);
785: }
786: ;
787:
788: notype_direct_decl:
789: T_NAME {
790: $$ = dname(getsym($1));
791: }
792: | T_LPARN type_decl T_RPARN {
793: $$ = $2;
794: }
795: | notype_direct_decl T_LBRACK T_RBRACK {
796: $$ = addarray($1, 0, 0);
797: }
798: | notype_direct_decl T_LBRACK constant T_RBRACK {
799: $$ = addarray($1, 1, toicon($3));
800: }
801: | notype_direct_decl param_list {
802: $$ = addfunc($1, $2);
803: popdecl();
804: blklev--;
805: }
806: ;
807:
808: type_decl:
809: type_direct_decl {
810: $$ = $1;
811: }
812: | pointer type_direct_decl {
813: $$ = addptr($2, $1);
814: }
815: ;
816:
817: type_direct_decl:
818: identifier {
819: $$ = dname(getsym($1));
820: }
821: | T_LPARN type_decl T_RPARN {
822: $$ = $2;
823: }
824: | type_direct_decl T_LBRACK T_RBRACK {
825: $$ = addarray($1, 0, 0);
826: }
827: | type_direct_decl T_LBRACK constant T_RBRACK {
828: $$ = addarray($1, 1, toicon($3));
829: }
830: | type_direct_decl param_list {
831: $$ = addfunc($1, $2);
832: popdecl();
833: blklev--;
834: }
835: ;
836:
837: /*
838: * param_decl and notype_param_decl exist to avoid a conflict in
839: * argument lists. A typename enclosed in parens should always be
840: * treated as a typename, not an argument.
841: * "typedef int a; f(int (a));" is "typedef int a; f(int foo(a));"
842: * not "typedef int a; f(int a);"
843: */
844: param_decl:
845: direct_param_decl {
846: $$ = $1;
847: }
848: | pointer direct_param_decl {
849: $$ = addptr($2, $1);
850: }
851: ;
852:
853: direct_param_decl:
854: identifier {
855: $$ = dname(getsym($1));
856: }
857: | T_LPARN notype_param_decl T_RPARN {
858: $$ = $2;
859: }
860: | direct_param_decl T_LBRACK T_RBRACK {
861: $$ = addarray($1, 0, 0);
862: }
863: | direct_param_decl T_LBRACK constant T_RBRACK {
864: $$ = addarray($1, 1, toicon($3));
865: }
866: | direct_param_decl param_list {
867: $$ = addfunc($1, $2);
868: popdecl();
869: blklev--;
870: }
871: ;
872:
873: notype_param_decl:
874: direct_notype_param_decl {
875: $$ = $1;
876: }
877: | pointer direct_notype_param_decl {
878: $$ = addptr($2, $1);
879: }
880: ;
881:
882: direct_notype_param_decl:
883: T_NAME {
884: $$ = dname(getsym($1));
885: }
886: | T_LPARN notype_param_decl T_RPARN {
887: $$ = $2;
888: }
889: | direct_notype_param_decl T_LBRACK T_RBRACK {
890: $$ = addarray($1, 0, 0);
891: }
892: | direct_notype_param_decl T_LBRACK constant T_RBRACK {
893: $$ = addarray($1, 1, toicon($3));
894: }
895: | direct_notype_param_decl param_list {
896: $$ = addfunc($1, $2);
897: popdecl();
898: blklev--;
899: }
900: ;
901:
902: pointer:
903: asterisk {
904: $$ = $1;
905: }
906: | asterisk type_qualifier_list {
907: $$ = mergepq($1, $2);
908: }
909: | asterisk pointer {
910: $$ = mergepq($1, $2);
911: }
912: | asterisk type_qualifier_list pointer {
913: $$ = mergepq(mergepq($1, $2), $3);
914: }
915: ;
916:
917: asterisk:
918: T_MULT {
919: $$ = xcalloc(1, sizeof (pqinf_t));
920: $$->p_pcnt = 1;
921: }
922: ;
923:
924: type_qualifier_list:
925: type_qualifier {
926: $$ = $1;
927: }
928: | type_qualifier_list type_qualifier {
929: $$ = mergepq($1, $2);
930: }
931: ;
932:
933: type_qualifier:
934: T_QUAL {
935: $$ = xcalloc(1, sizeof (pqinf_t));
936: if (tflag) {
937: /* const and volatile illegal in traditional C */
938: warning(269);
939: } else {
940: if ($1 == CONST) {
941: $$->p_const = 1;
942: } else {
943: $$->p_volatile = 1;
944: }
945: }
946: }
947: ;
948:
949: param_list:
950: id_list_lparn identifier_list T_RPARN {
951: $$ = $2;
952: }
953: | abs_decl_param_list {
954: $$ = $1;
955: }
956: ;
957:
958: id_list_lparn:
959: T_LPARN {
960: blklev++;
961: pushdecl(PARG);
962: }
963: ;
964:
965: identifier_list:
966: T_NAME {
967: $$ = iname(getsym($1));
968: }
969: | identifier_list T_COMMA T_NAME {
970: $$ = lnklst($1, iname(getsym($3)));
971: }
972: | identifier_list error {
973: $$ = $1;
974: }
975: ;
976:
977: abs_decl_param_list:
978: abs_decl_lparn T_RPARN {
979: $$ = NULL;
980: }
981: | abs_decl_lparn vararg_parameter_type_list T_RPARN {
1.3 jpo 982: dcs->d_proto = 1;
1.1 cgd 983: $$ = $2;
984: }
985: | abs_decl_lparn error T_RPARN {
986: $$ = NULL;
987: }
988: ;
989:
990: abs_decl_lparn:
991: T_LPARN {
992: blklev++;
993: pushdecl(PARG);
994: }
995: ;
996:
997: vararg_parameter_type_list:
998: parameter_type_list {
999: $$ = $1;
1000: }
1001: | parameter_type_list T_COMMA T_ELLIPSE {
1.3 jpo 1002: dcs->d_vararg = 1;
1.1 cgd 1003: $$ = $1;
1004: }
1005: | T_ELLIPSE {
1006: if (sflag) {
1007: /* ANSI C requires formal parameter before "..." */
1008: error(84);
1009: } else if (!tflag) {
1010: /* ANSI C requires formal parameter before "..." */
1011: warning(84);
1012: }
1.3 jpo 1013: dcs->d_vararg = 1;
1.1 cgd 1014: $$ = NULL;
1015: }
1016: ;
1017:
1018: parameter_type_list:
1019: parameter_declaration {
1020: $$ = $1;
1021: }
1022: | parameter_type_list T_COMMA parameter_declaration {
1023: $$ = lnklst($1, $3);
1024: }
1025: ;
1026:
1027: parameter_declaration:
1028: declmods deftyp {
1029: $$ = decl1arg(aname(), 0);
1030: }
1031: | declspecs deftyp {
1032: $$ = decl1arg(aname(), 0);
1033: }
1034: | declmods deftyp notype_param_decl {
1035: $$ = decl1arg($3, 0);
1036: }
1037: /*
1038: * param_decl is needed because of following conflict:
1039: * "typedef int a; f(int (a));" could be parsed as
1040: * "function with argument a of type int", or
1041: * "function with an abstract argument of type function".
1042: * This grammar realizes the second case.
1043: */
1044: | declspecs deftyp param_decl {
1045: $$ = decl1arg($3, 0);
1046: }
1047: | declmods deftyp abs_decl {
1048: $$ = decl1arg($3, 0);
1049: }
1050: | declspecs deftyp abs_decl {
1051: $$ = decl1arg($3, 0);
1052: }
1053: ;
1054:
1055: initializer:
1056: init_expr
1057: ;
1058:
1059: init_expr:
1060: expr %prec T_COMMA {
1061: mkinit($1);
1062: }
1063: | init_lbrace init_expr_list init_rbrace
1064: | init_lbrace init_expr_list T_COMMA init_rbrace
1065: | error
1066: ;
1067:
1068: init_expr_list:
1069: init_expr %prec T_COMMA
1070: | init_expr_list T_COMMA init_expr
1071: ;
1072:
1073: init_lbrace:
1074: T_LBRACE {
1075: initlbr();
1076: }
1077: ;
1078:
1079: init_rbrace:
1080: T_RBRACE {
1081: initrbr();
1082: }
1083: ;
1084:
1085: type_name:
1086: {
1087: pushdecl(ABSTRACT);
1088: } abstract_declaration {
1089: popdecl();
1090: $$ = $2->s_type;
1091: }
1092: ;
1093:
1094: abstract_declaration:
1095: noclass_declmods deftyp {
1096: $$ = decl1abs(aname());
1097: }
1098: | noclass_declspecs deftyp {
1099: $$ = decl1abs(aname());
1100: }
1101: | noclass_declmods deftyp abs_decl {
1102: $$ = decl1abs($3);
1103: }
1104: | noclass_declspecs deftyp abs_decl {
1105: $$ = decl1abs($3);
1106: }
1107: ;
1108:
1109: abs_decl:
1110: pointer {
1111: $$ = addptr(aname(), $1);
1112: }
1113: | direct_abs_decl {
1114: $$ = $1;
1115: }
1116: | pointer direct_abs_decl {
1117: $$ = addptr($2, $1);
1118: }
1119: ;
1120:
1121: direct_abs_decl:
1122: T_LPARN abs_decl T_RPARN {
1123: $$ = $2;
1124: }
1125: | T_LBRACK T_RBRACK {
1126: $$ = addarray(aname(), 0, 0);
1127: }
1128: | T_LBRACK constant T_RBRACK {
1129: $$ = addarray(aname(), 1, toicon($2));
1130: }
1131: | direct_abs_decl T_LBRACK T_RBRACK {
1132: $$ = addarray($1, 0, 0);
1133: }
1134: | direct_abs_decl T_LBRACK constant T_RBRACK {
1135: $$ = addarray($1, 1, toicon($3));
1136: }
1137: | abs_decl_param_list {
1138: $$ = addfunc(aname(), $1);
1139: popdecl();
1140: blklev--;
1141: }
1142: | direct_abs_decl abs_decl_param_list {
1143: $$ = addfunc($1, $2);
1144: popdecl();
1145: blklev--;
1146: }
1147: ;
1148:
1149: stmnt:
1150: labeled_stmnt
1151: | expr_stmnt
1152: | comp_stmnt
1153: | selection_stmnt
1154: | iteration_stmnt
1155: | jump_stmnt {
1156: ftflg = 0;
1157: }
1158: ;
1159:
1160: labeled_stmnt:
1161: label stmnt
1162: ;
1163:
1164: label:
1165: identifier T_COLON {
1166: symtyp = FLAB;
1167: label(T_NAME, getsym($1), NULL);
1168: }
1169: | T_CASE constant T_COLON {
1170: label(T_CASE, NULL, $2);
1171: ftflg = 1;
1172: }
1173: | T_DEFAULT T_COLON {
1174: label(T_DEFAULT, NULL, NULL);
1175: ftflg = 1;
1176: }
1177: ;
1178:
1179: comp_stmnt:
1180: compstmnt_lbrace declaration_list opt_stmnt_list compstmnt_rbrace
1181: | compstmnt_lbrace opt_stmnt_list compstmnt_rbrace
1182: ;
1183:
1184: compstmnt_lbrace:
1185: T_LBRACE {
1186: blklev++;
1187: mblklev++;
1188: pushdecl(AUTO);
1189: }
1190: ;
1191:
1192: compstmnt_rbrace:
1193: T_RBRACE {
1194: popdecl();
1195: freeblk();
1196: mblklev--;
1197: blklev--;
1198: ftflg = 0;
1199: }
1200: ;
1201:
1202: opt_stmnt_list:
1203: /* empty */
1204: | stmnt_list
1205: ;
1206:
1207: stmnt_list:
1208: stmnt
1209: | stmnt_list stmnt
1210: | stmnt_list error T_SEMI
1211: ;
1212:
1213: expr_stmnt:
1214: expr T_SEMI {
1215: expr($1, 0, 0);
1216: ftflg = 0;
1217: }
1218: | T_SEMI {
1219: ftflg = 0;
1220: }
1221: ;
1222:
1223: selection_stmnt:
1224: if_without_else {
1225: if2();
1226: if3(0);
1227: }
1228: | if_without_else T_ELSE {
1229: if2();
1230: } stmnt {
1231: if3(1);
1232: }
1233: | if_without_else T_ELSE error {
1234: if3(0);
1235: }
1236: | switch_expr stmnt {
1237: switch2();
1238: }
1239: | switch_expr error {
1240: switch2();
1241: }
1242: ;
1243:
1244: if_without_else:
1245: if_expr stmnt
1246: | if_expr error
1247: ;
1248:
1249: if_expr:
1250: T_IF T_LPARN expr T_RPARN {
1251: if1($3);
1252: }
1253: ;
1254:
1255: switch_expr:
1256: T_SWITCH T_LPARN expr T_RPARN {
1257: switch1($3);
1258: }
1259: ;
1260:
1261: iteration_stmnt:
1262: while_expr stmnt {
1263: while2();
1264: }
1265: | while_expr error {
1266: while2();
1267: }
1268: | do stmnt do_while_expr {
1269: do2($3);
1270: ftflg = 0;
1271: }
1272: | do error {
1273: do2(NULL);
1274: }
1275: | for_exprs stmnt {
1276: for2();
1277: }
1278: | for_exprs error {
1279: for2();
1280: }
1281: ;
1282:
1283: while_expr:
1284: T_WHILE T_LPARN expr T_RPARN {
1285: while1($3);
1286: }
1287: ;
1288:
1289: do:
1290: T_DO {
1291: do1();
1292: }
1293: ;
1294:
1295: do_while_expr:
1296: T_WHILE T_LPARN expr T_RPARN T_SEMI {
1297: $$ = $3;
1298: }
1299: ;
1300:
1301: for_exprs:
1302: T_FOR T_LPARN opt_expr T_SEMI opt_expr T_SEMI opt_expr T_RPARN {
1303: for1($3, $5, $7);
1304: }
1305: ;
1306:
1307: opt_expr:
1308: /* empty */ {
1309: $$ = NULL;
1310: }
1311: | expr {
1312: $$ = $1;
1313: }
1314: ;
1315:
1316: jump_stmnt:
1317: goto identifier T_SEMI {
1318: dogoto(getsym($2));
1319: }
1320: | goto error T_SEMI {
1321: symtyp = FVFT;
1322: }
1323: | T_CONTINUE T_SEMI {
1324: docont();
1325: }
1326: | T_BREAK T_SEMI {
1327: dobreak();
1328: }
1329: | T_RETURN T_SEMI {
1330: doreturn(NULL);
1331: }
1332: | T_RETURN expr T_SEMI {
1333: doreturn($2);
1334: }
1335: ;
1336:
1337: goto:
1338: T_GOTO {
1339: symtyp = FLAB;
1340: }
1341: ;
1342:
1343: declaration_list:
1344: declaration
1345: | declaration_list declaration
1346: ;
1347:
1348: constant:
1349: expr %prec T_COMMA {
1350: $$ = $1;
1351: }
1352: ;
1353:
1354: expr:
1355: expr T_MULT expr {
1356: $$ = build(MULT, $1, $3);
1357: }
1358: | expr T_DIVOP expr {
1359: $$ = build($2, $1, $3);
1360: }
1361: | expr T_ADDOP expr {
1362: $$ = build($2, $1, $3);
1363: }
1364: | expr T_SHFTOP expr {
1365: $$ = build($2, $1, $3);
1366: }
1367: | expr T_RELOP expr {
1368: $$ = build($2, $1, $3);
1369: }
1370: | expr T_EQOP expr {
1371: $$ = build($2, $1, $3);
1372: }
1373: | expr T_AND expr {
1374: $$ = build(AND, $1, $3);
1375: }
1376: | expr T_XOR expr {
1377: $$ = build(XOR, $1, $3);
1378: }
1379: | expr T_OR expr {
1380: $$ = build(OR, $1, $3);
1381: }
1382: | expr T_LOGAND expr {
1383: $$ = build(LOGAND, $1, $3);
1384: }
1385: | expr T_LOGOR expr {
1386: $$ = build(LOGOR, $1, $3);
1387: }
1388: | expr T_QUEST expr T_COLON expr {
1389: $$ = build(QUEST, $1, build(COLON, $3, $5));
1390: }
1391: | expr T_ASSIGN expr {
1392: $$ = build(ASSIGN, $1, $3);
1393: }
1394: | expr T_OPASS expr {
1395: $$ = build($2, $1, $3);
1396: }
1397: | expr T_COMMA expr {
1398: $$ = build(COMMA, $1, $3);
1399: }
1400: | term {
1401: $$ = $1;
1402: }
1403: ;
1404:
1405: term:
1406: T_NAME {
1407: /* XXX realy neccessary? */
1408: if (yychar < 0)
1409: yychar = yylex();
1410: $$ = getnnode(getsym($1), yychar);
1411: }
1412: | string {
1413: $$ = getsnode($1);
1414: }
1415: | T_CON {
1416: $$ = getcnode(gettyp($1->v_tspec), $1);
1417: }
1418: | T_LPARN expr T_RPARN {
1419: if ($2 != NULL)
1420: $2->tn_parn = 1;
1421: $$ = $2;
1422: }
1423: | term T_INCDEC {
1424: $$ = build($2 == INC ? INCAFT : DECAFT, $1, NULL);
1425: }
1426: | T_INCDEC term {
1427: $$ = build($1 == INC ? INCBEF : DECBEF, $2, NULL);
1428: }
1429: | T_MULT term {
1430: $$ = build(STAR, $2, NULL);
1431: }
1432: | T_AND term {
1433: $$ = build(AMPER, $2, NULL);
1434: }
1435: | T_UNOP term {
1436: $$ = build($1, $2, NULL);
1437: }
1438: | T_ADDOP term {
1439: if (tflag && $1 == PLUS) {
1440: /* unary + is illegal in traditional C */
1441: warning(100);
1442: }
1443: $$ = build($1 == PLUS ? UPLUS : UMINUS, $2, NULL);
1444: }
1445: | term T_LBRACK expr T_RBRACK {
1446: $$ = build(STAR, build(PLUS, $1, $3), NULL);
1447: }
1448: | term T_LPARN T_RPARN {
1449: $$ = funccall($1, NULL);
1450: }
1451: | term T_LPARN func_arg_list T_RPARN {
1452: $$ = funccall($1, $3);
1453: }
1454: | term point_or_arrow T_NAME {
1455: if ($1 != NULL) {
1456: sym_t *msym;
1457: /* XXX strmemb should be integrated in build() */
1458: if ($2 == ARROW) {
1459: /* must to this before strmemb is called */
1460: $1 = cconv($1);
1461: }
1462: msym = strmemb($1, $2, getsym($3));
1463: $$ = build($2, $1, getnnode(msym, 0));
1464: } else {
1465: $$ = NULL;
1466: }
1467: }
1468: | T_SIZEOF term %prec T_SIZEOF {
1469: if (($$ = $2 == NULL ? NULL : bldszof($2->tn_type)) != NULL)
1470: chkmisc($2, 0, 0, 0, 0, 0, 1);
1471: }
1472: | T_SIZEOF T_LPARN type_name T_RPARN %prec T_SIZEOF {
1473: $$ = bldszof($3);
1474: }
1475: | T_LPARN type_name T_RPARN term %prec T_UNOP {
1476: $$ = cast($4, $2);
1477: }
1478: ;
1479:
1480: string:
1481: T_STRING {
1482: $$ = $1;
1483: }
1484: | T_STRING string2 {
1485: $$ = catstrg($1, $2);
1486: }
1487: ;
1488:
1489: string2:
1490: T_STRING {
1491: if (tflag) {
1492: /* concatenated strings are illegal in traditional C */
1493: warning(219);
1494: }
1495: $$ = $1;
1496: }
1497: | string2 T_STRING {
1498: $$ = catstrg($1, $2);
1499: }
1500: ;
1501:
1502: func_arg_list:
1503: expr %prec T_COMMA {
1504: $$ = funcarg(NULL, $1);
1505: }
1506: | func_arg_list T_COMMA expr {
1507: $$ = funcarg($1, $3);
1508: }
1509: ;
1510:
1511: point_or_arrow:
1512: T_STROP {
1513: symtyp = FMOS;
1514: $$ = $1;
1515: }
1516: ;
1517:
1518: identifier:
1519: T_NAME {
1520: $$ = $1;
1521: }
1522: | T_TYPENAME {
1523: $$ = $1;
1524: }
1525: ;
1526:
1527: %%
1528:
1529: /* ARGSUSED */
1530: int
1531: yyerror(msg)
1532: char *msg;
1533: {
1534: error(249);
1535: if (++sytxerr >= 5)
1536: norecover();
1537: return (0);
1538: }
1539:
1540: /*
1541: * Gets a node for a constant and returns the value of this constant
1542: * as integer.
1543: * Is the node not constant or too large for int or of type float,
1544: * a warning will be printed.
1545: *
1546: * toicon() should be used only inside declarations. If it is used in
1547: * expressions, it frees the memory used for the expression.
1548: */
1549: static int
1550: toicon(tn)
1551: tnode_t *tn;
1552: {
1553: int i;
1554: tspec_t t;
1555: val_t *v;
1556:
1557: v = constant(tn);
1558:
1559: /*
1560: * Abstract declarations are used inside expression. To free
1561: * the memory would be a fatal error.
1562: */
1.3 jpo 1563: if (dcs->d_ctx != ABSTRACT)
1.1 cgd 1564: tfreeblk();
1565:
1566: if ((t = v->v_tspec) == FLOAT || t == DOUBLE || t == LDOUBLE) {
1567: i = (int)v->v_ldbl;
1568: /* integral constant expression expected */
1569: error(55);
1570: } else {
1571: i = (int)v->v_quad;
1572: if (isutyp(t)) {
1573: if ((u_quad_t)v->v_quad > INT_MAX) {
1574: /* integral constant too large */
1575: warning(56);
1576: }
1577: } else {
1578: if (v->v_quad > INT_MAX || v->v_quad < INT_MIN) {
1579: /* integral constant too large */
1580: warning(56);
1581: }
1582: }
1583: }
1584: free(v);
1585: return (i);
1586: }
1587:
1588: static void
1589: idecl(decl, initflg)
1590: sym_t *decl;
1591: int initflg;
1592: {
1593: initerr = 0;
1594: initsym = decl;
1595:
1.3 jpo 1596: switch (dcs->d_ctx) {
1.1 cgd 1597: case EXTERN:
1598: decl1ext(decl, initflg);
1599: break;
1600: case ARG:
1601: (void)decl1arg(decl, initflg);
1602: break;
1603: case AUTO:
1604: decl1loc(decl, initflg);
1605: break;
1606: default:
1607: lerror("idecl()");
1608: }
1609:
1610: if (initflg && !initerr)
1611: prepinit();
1612: }
CVSweb <webmaster@jp.NetBSD.org>