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