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