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