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