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