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