cgram.y revision 1.3 1 %{
2 /* $NetBSD: cgram.y,v 1.3 1995/10/02 17:08:31 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.3 1995/10/02 17:08:31 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 (tflag) {
937 /* const and volatile illegal in traditional C */
938 warning(269);
939 } else {
940 if ($1 == CONST) {
941 $$->p_const = 1;
942 } else {
943 $$->p_volatile = 1;
944 }
945 }
946 }
947 ;
948
949 param_list:
950 id_list_lparn identifier_list T_RPARN {
951 $$ = $2;
952 }
953 | abs_decl_param_list {
954 $$ = $1;
955 }
956 ;
957
958 id_list_lparn:
959 T_LPARN {
960 blklev++;
961 pushdecl(PARG);
962 }
963 ;
964
965 identifier_list:
966 T_NAME {
967 $$ = iname(getsym($1));
968 }
969 | identifier_list T_COMMA T_NAME {
970 $$ = lnklst($1, iname(getsym($3)));
971 }
972 | identifier_list error {
973 $$ = $1;
974 }
975 ;
976
977 abs_decl_param_list:
978 abs_decl_lparn T_RPARN {
979 $$ = NULL;
980 }
981 | abs_decl_lparn vararg_parameter_type_list T_RPARN {
982 dcs->d_proto = 1;
983 $$ = $2;
984 }
985 | abs_decl_lparn error T_RPARN {
986 $$ = NULL;
987 }
988 ;
989
990 abs_decl_lparn:
991 T_LPARN {
992 blklev++;
993 pushdecl(PARG);
994 }
995 ;
996
997 vararg_parameter_type_list:
998 parameter_type_list {
999 $$ = $1;
1000 }
1001 | parameter_type_list T_COMMA T_ELLIPSE {
1002 dcs->d_vararg = 1;
1003 $$ = $1;
1004 }
1005 | T_ELLIPSE {
1006 if (sflag) {
1007 /* ANSI C requires formal parameter before "..." */
1008 error(84);
1009 } else if (!tflag) {
1010 /* ANSI C requires formal parameter before "..." */
1011 warning(84);
1012 }
1013 dcs->d_vararg = 1;
1014 $$ = NULL;
1015 }
1016 ;
1017
1018 parameter_type_list:
1019 parameter_declaration {
1020 $$ = $1;
1021 }
1022 | parameter_type_list T_COMMA parameter_declaration {
1023 $$ = lnklst($1, $3);
1024 }
1025 ;
1026
1027 parameter_declaration:
1028 declmods deftyp {
1029 $$ = decl1arg(aname(), 0);
1030 }
1031 | declspecs deftyp {
1032 $$ = decl1arg(aname(), 0);
1033 }
1034 | declmods deftyp notype_param_decl {
1035 $$ = decl1arg($3, 0);
1036 }
1037 /*
1038 * param_decl is needed because of following conflict:
1039 * "typedef int a; f(int (a));" could be parsed as
1040 * "function with argument a of type int", or
1041 * "function with an abstract argument of type function".
1042 * This grammar realizes the second case.
1043 */
1044 | declspecs deftyp param_decl {
1045 $$ = decl1arg($3, 0);
1046 }
1047 | declmods deftyp abs_decl {
1048 $$ = decl1arg($3, 0);
1049 }
1050 | declspecs deftyp abs_decl {
1051 $$ = decl1arg($3, 0);
1052 }
1053 ;
1054
1055 initializer:
1056 init_expr
1057 ;
1058
1059 init_expr:
1060 expr %prec T_COMMA {
1061 mkinit($1);
1062 }
1063 | init_lbrace init_expr_list init_rbrace
1064 | init_lbrace init_expr_list T_COMMA init_rbrace
1065 | error
1066 ;
1067
1068 init_expr_list:
1069 init_expr %prec T_COMMA
1070 | init_expr_list T_COMMA init_expr
1071 ;
1072
1073 init_lbrace:
1074 T_LBRACE {
1075 initlbr();
1076 }
1077 ;
1078
1079 init_rbrace:
1080 T_RBRACE {
1081 initrbr();
1082 }
1083 ;
1084
1085 type_name:
1086 {
1087 pushdecl(ABSTRACT);
1088 } abstract_declaration {
1089 popdecl();
1090 $$ = $2->s_type;
1091 }
1092 ;
1093
1094 abstract_declaration:
1095 noclass_declmods deftyp {
1096 $$ = decl1abs(aname());
1097 }
1098 | noclass_declspecs deftyp {
1099 $$ = decl1abs(aname());
1100 }
1101 | noclass_declmods deftyp abs_decl {
1102 $$ = decl1abs($3);
1103 }
1104 | noclass_declspecs deftyp abs_decl {
1105 $$ = decl1abs($3);
1106 }
1107 ;
1108
1109 abs_decl:
1110 pointer {
1111 $$ = addptr(aname(), $1);
1112 }
1113 | direct_abs_decl {
1114 $$ = $1;
1115 }
1116 | pointer direct_abs_decl {
1117 $$ = addptr($2, $1);
1118 }
1119 ;
1120
1121 direct_abs_decl:
1122 T_LPARN abs_decl T_RPARN {
1123 $$ = $2;
1124 }
1125 | T_LBRACK T_RBRACK {
1126 $$ = addarray(aname(), 0, 0);
1127 }
1128 | T_LBRACK constant T_RBRACK {
1129 $$ = addarray(aname(), 1, toicon($2));
1130 }
1131 | direct_abs_decl T_LBRACK T_RBRACK {
1132 $$ = addarray($1, 0, 0);
1133 }
1134 | direct_abs_decl T_LBRACK constant T_RBRACK {
1135 $$ = addarray($1, 1, toicon($3));
1136 }
1137 | abs_decl_param_list {
1138 $$ = addfunc(aname(), $1);
1139 popdecl();
1140 blklev--;
1141 }
1142 | direct_abs_decl abs_decl_param_list {
1143 $$ = addfunc($1, $2);
1144 popdecl();
1145 blklev--;
1146 }
1147 ;
1148
1149 stmnt:
1150 labeled_stmnt
1151 | expr_stmnt
1152 | comp_stmnt
1153 | selection_stmnt
1154 | iteration_stmnt
1155 | jump_stmnt {
1156 ftflg = 0;
1157 }
1158 ;
1159
1160 labeled_stmnt:
1161 label stmnt
1162 ;
1163
1164 label:
1165 identifier T_COLON {
1166 symtyp = FLAB;
1167 label(T_NAME, getsym($1), NULL);
1168 }
1169 | T_CASE constant T_COLON {
1170 label(T_CASE, NULL, $2);
1171 ftflg = 1;
1172 }
1173 | T_DEFAULT T_COLON {
1174 label(T_DEFAULT, NULL, NULL);
1175 ftflg = 1;
1176 }
1177 ;
1178
1179 comp_stmnt:
1180 compstmnt_lbrace declaration_list opt_stmnt_list compstmnt_rbrace
1181 | compstmnt_lbrace opt_stmnt_list compstmnt_rbrace
1182 ;
1183
1184 compstmnt_lbrace:
1185 T_LBRACE {
1186 blklev++;
1187 mblklev++;
1188 pushdecl(AUTO);
1189 }
1190 ;
1191
1192 compstmnt_rbrace:
1193 T_RBRACE {
1194 popdecl();
1195 freeblk();
1196 mblklev--;
1197 blklev--;
1198 ftflg = 0;
1199 }
1200 ;
1201
1202 opt_stmnt_list:
1203 /* empty */
1204 | stmnt_list
1205 ;
1206
1207 stmnt_list:
1208 stmnt
1209 | stmnt_list stmnt
1210 | stmnt_list error T_SEMI
1211 ;
1212
1213 expr_stmnt:
1214 expr T_SEMI {
1215 expr($1, 0, 0);
1216 ftflg = 0;
1217 }
1218 | T_SEMI {
1219 ftflg = 0;
1220 }
1221 ;
1222
1223 selection_stmnt:
1224 if_without_else {
1225 if2();
1226 if3(0);
1227 }
1228 | if_without_else T_ELSE {
1229 if2();
1230 } stmnt {
1231 if3(1);
1232 }
1233 | if_without_else T_ELSE error {
1234 if3(0);
1235 }
1236 | switch_expr stmnt {
1237 switch2();
1238 }
1239 | switch_expr error {
1240 switch2();
1241 }
1242 ;
1243
1244 if_without_else:
1245 if_expr stmnt
1246 | if_expr error
1247 ;
1248
1249 if_expr:
1250 T_IF T_LPARN expr T_RPARN {
1251 if1($3);
1252 }
1253 ;
1254
1255 switch_expr:
1256 T_SWITCH T_LPARN expr T_RPARN {
1257 switch1($3);
1258 }
1259 ;
1260
1261 iteration_stmnt:
1262 while_expr stmnt {
1263 while2();
1264 }
1265 | while_expr error {
1266 while2();
1267 }
1268 | do stmnt do_while_expr {
1269 do2($3);
1270 ftflg = 0;
1271 }
1272 | do error {
1273 do2(NULL);
1274 }
1275 | for_exprs stmnt {
1276 for2();
1277 }
1278 | for_exprs error {
1279 for2();
1280 }
1281 ;
1282
1283 while_expr:
1284 T_WHILE T_LPARN expr T_RPARN {
1285 while1($3);
1286 }
1287 ;
1288
1289 do:
1290 T_DO {
1291 do1();
1292 }
1293 ;
1294
1295 do_while_expr:
1296 T_WHILE T_LPARN expr T_RPARN T_SEMI {
1297 $$ = $3;
1298 }
1299 ;
1300
1301 for_exprs:
1302 T_FOR T_LPARN opt_expr T_SEMI opt_expr T_SEMI opt_expr T_RPARN {
1303 for1($3, $5, $7);
1304 }
1305 ;
1306
1307 opt_expr:
1308 /* empty */ {
1309 $$ = NULL;
1310 }
1311 | expr {
1312 $$ = $1;
1313 }
1314 ;
1315
1316 jump_stmnt:
1317 goto identifier T_SEMI {
1318 dogoto(getsym($2));
1319 }
1320 | goto error T_SEMI {
1321 symtyp = FVFT;
1322 }
1323 | T_CONTINUE T_SEMI {
1324 docont();
1325 }
1326 | T_BREAK T_SEMI {
1327 dobreak();
1328 }
1329 | T_RETURN T_SEMI {
1330 doreturn(NULL);
1331 }
1332 | T_RETURN expr T_SEMI {
1333 doreturn($2);
1334 }
1335 ;
1336
1337 goto:
1338 T_GOTO {
1339 symtyp = FLAB;
1340 }
1341 ;
1342
1343 declaration_list:
1344 declaration
1345 | declaration_list declaration
1346 ;
1347
1348 constant:
1349 expr %prec T_COMMA {
1350 $$ = $1;
1351 }
1352 ;
1353
1354 expr:
1355 expr T_MULT expr {
1356 $$ = build(MULT, $1, $3);
1357 }
1358 | expr T_DIVOP expr {
1359 $$ = build($2, $1, $3);
1360 }
1361 | expr T_ADDOP expr {
1362 $$ = build($2, $1, $3);
1363 }
1364 | expr T_SHFTOP expr {
1365 $$ = build($2, $1, $3);
1366 }
1367 | expr T_RELOP expr {
1368 $$ = build($2, $1, $3);
1369 }
1370 | expr T_EQOP expr {
1371 $$ = build($2, $1, $3);
1372 }
1373 | expr T_AND expr {
1374 $$ = build(AND, $1, $3);
1375 }
1376 | expr T_XOR expr {
1377 $$ = build(XOR, $1, $3);
1378 }
1379 | expr T_OR expr {
1380 $$ = build(OR, $1, $3);
1381 }
1382 | expr T_LOGAND expr {
1383 $$ = build(LOGAND, $1, $3);
1384 }
1385 | expr T_LOGOR expr {
1386 $$ = build(LOGOR, $1, $3);
1387 }
1388 | expr T_QUEST expr T_COLON expr {
1389 $$ = build(QUEST, $1, build(COLON, $3, $5));
1390 }
1391 | expr T_ASSIGN expr {
1392 $$ = build(ASSIGN, $1, $3);
1393 }
1394 | expr T_OPASS expr {
1395 $$ = build($2, $1, $3);
1396 }
1397 | expr T_COMMA expr {
1398 $$ = build(COMMA, $1, $3);
1399 }
1400 | term {
1401 $$ = $1;
1402 }
1403 ;
1404
1405 term:
1406 T_NAME {
1407 /* XXX realy neccessary? */
1408 if (yychar < 0)
1409 yychar = yylex();
1410 $$ = getnnode(getsym($1), yychar);
1411 }
1412 | string {
1413 $$ = getsnode($1);
1414 }
1415 | T_CON {
1416 $$ = getcnode(gettyp($1->v_tspec), $1);
1417 }
1418 | T_LPARN expr T_RPARN {
1419 if ($2 != NULL)
1420 $2->tn_parn = 1;
1421 $$ = $2;
1422 }
1423 | term T_INCDEC {
1424 $$ = build($2 == INC ? INCAFT : DECAFT, $1, NULL);
1425 }
1426 | T_INCDEC term {
1427 $$ = build($1 == INC ? INCBEF : DECBEF, $2, NULL);
1428 }
1429 | T_MULT term {
1430 $$ = build(STAR, $2, NULL);
1431 }
1432 | T_AND term {
1433 $$ = build(AMPER, $2, NULL);
1434 }
1435 | T_UNOP term {
1436 $$ = build($1, $2, NULL);
1437 }
1438 | T_ADDOP term {
1439 if (tflag && $1 == PLUS) {
1440 /* unary + is illegal in traditional C */
1441 warning(100);
1442 }
1443 $$ = build($1 == PLUS ? UPLUS : UMINUS, $2, NULL);
1444 }
1445 | term T_LBRACK expr T_RBRACK {
1446 $$ = build(STAR, build(PLUS, $1, $3), NULL);
1447 }
1448 | term T_LPARN T_RPARN {
1449 $$ = funccall($1, NULL);
1450 }
1451 | term T_LPARN func_arg_list T_RPARN {
1452 $$ = funccall($1, $3);
1453 }
1454 | term point_or_arrow T_NAME {
1455 if ($1 != NULL) {
1456 sym_t *msym;
1457 /* XXX strmemb should be integrated in build() */
1458 if ($2 == ARROW) {
1459 /* must to this before strmemb is called */
1460 $1 = cconv($1);
1461 }
1462 msym = strmemb($1, $2, getsym($3));
1463 $$ = build($2, $1, getnnode(msym, 0));
1464 } else {
1465 $$ = NULL;
1466 }
1467 }
1468 | T_SIZEOF term %prec T_SIZEOF {
1469 if (($$ = $2 == NULL ? NULL : bldszof($2->tn_type)) != NULL)
1470 chkmisc($2, 0, 0, 0, 0, 0, 1);
1471 }
1472 | T_SIZEOF T_LPARN type_name T_RPARN %prec T_SIZEOF {
1473 $$ = bldszof($3);
1474 }
1475 | T_LPARN type_name T_RPARN term %prec T_UNOP {
1476 $$ = cast($4, $2);
1477 }
1478 ;
1479
1480 string:
1481 T_STRING {
1482 $$ = $1;
1483 }
1484 | T_STRING string2 {
1485 $$ = catstrg($1, $2);
1486 }
1487 ;
1488
1489 string2:
1490 T_STRING {
1491 if (tflag) {
1492 /* concatenated strings are illegal in traditional C */
1493 warning(219);
1494 }
1495 $$ = $1;
1496 }
1497 | string2 T_STRING {
1498 $$ = catstrg($1, $2);
1499 }
1500 ;
1501
1502 func_arg_list:
1503 expr %prec T_COMMA {
1504 $$ = funcarg(NULL, $1);
1505 }
1506 | func_arg_list T_COMMA expr {
1507 $$ = funcarg($1, $3);
1508 }
1509 ;
1510
1511 point_or_arrow:
1512 T_STROP {
1513 symtyp = FMOS;
1514 $$ = $1;
1515 }
1516 ;
1517
1518 identifier:
1519 T_NAME {
1520 $$ = $1;
1521 }
1522 | T_TYPENAME {
1523 $$ = $1;
1524 }
1525 ;
1526
1527 %%
1528
1529 /* ARGSUSED */
1530 int
1531 yyerror(msg)
1532 char *msg;
1533 {
1534 error(249);
1535 if (++sytxerr >= 5)
1536 norecover();
1537 return (0);
1538 }
1539
1540 /*
1541 * Gets a node for a constant and returns the value of this constant
1542 * as integer.
1543 * Is the node not constant or too large for int or of type float,
1544 * a warning will be printed.
1545 *
1546 * toicon() should be used only inside declarations. If it is used in
1547 * expressions, it frees the memory used for the expression.
1548 */
1549 static int
1550 toicon(tn)
1551 tnode_t *tn;
1552 {
1553 int i;
1554 tspec_t t;
1555 val_t *v;
1556
1557 v = constant(tn);
1558
1559 /*
1560 * Abstract declarations are used inside expression. To free
1561 * the memory would be a fatal error.
1562 */
1563 if (dcs->d_ctx != ABSTRACT)
1564 tfreeblk();
1565
1566 if ((t = v->v_tspec) == FLOAT || t == DOUBLE || t == LDOUBLE) {
1567 i = (int)v->v_ldbl;
1568 /* integral constant expression expected */
1569 error(55);
1570 } else {
1571 i = (int)v->v_quad;
1572 if (isutyp(t)) {
1573 if ((u_quad_t)v->v_quad > INT_MAX) {
1574 /* integral constant too large */
1575 warning(56);
1576 }
1577 } else {
1578 if (v->v_quad > INT_MAX || v->v_quad < INT_MIN) {
1579 /* integral constant too large */
1580 warning(56);
1581 }
1582 }
1583 }
1584 free(v);
1585 return (i);
1586 }
1587
1588 static void
1589 idecl(decl, initflg)
1590 sym_t *decl;
1591 int initflg;
1592 {
1593 initerr = 0;
1594 initsym = decl;
1595
1596 switch (dcs->d_ctx) {
1597 case EXTERN:
1598 decl1ext(decl, initflg);
1599 break;
1600 case ARG:
1601 (void)decl1arg(decl, initflg);
1602 break;
1603 case AUTO:
1604 decl1loc(decl, initflg);
1605 break;
1606 default:
1607 lerror("idecl()");
1608 }
1609
1610 if (initflg && !initerr)
1611 prepinit();
1612 }
1613