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