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