2 /* $NetBSD: cgram.y,v 1.8 1995/10/02 17:31:35 jpo Exp $ */
5 * Copyright (c) 1994, 1995 Jochen Pohl
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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
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.
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.
34 * $NetBSD: cgram.y,v 1.8 1995/10/02 17:31:35 jpo Exp $
35 * $DragonFly: src/usr.bin/xlint/lint1/cgram.y,v 1.6 2004/07/07 12:26:51 asmodai Exp $
44 * Contains the level of current declaration. 0 is extern.
45 * Used for symbol table entries.
50 * level for memory allocation. Normaly the same as blklev.
51 * An exeption is the declaration of arguments in prototypes. Memory
52 * for these can't be freed after the declaration, but symbols must
53 * be removed from the symbol table after the declaration.
57 static int toicon(tnode_t *);
58 static void idecl(sym_t *, int);
59 static void ignuptorp(void);
78 %token T_LBRACE T_RBRACE T_LBRACK T_RBRACK T_LPARN T_RPARN
81 %token <y_op> T_INCDEC
86 %token <y_op> T_SHFTOP
92 %token <y_op> T_LOGAND
96 %token <y_op> T_ASSIGN
102 /* storage classes (extern, static, auto, register and typedef) */
103 %token <y_scl> T_SCLASS
105 /* types (char, int, short, long, unsigned, signed, float, double, void) */
106 %token <y_tspec> T_TYPE
108 /* qualifiers (const, volatile) */
109 %token <y_tqual> T_QUAL
111 /* struct or union */
112 %token <y_tspec> T_SOU
117 /* remaining keywords */
133 %right T_ASSIGN T_OPASS
134 %right T_QUEST T_COLON
145 %right T_UNOP T_INCDEC T_SIZEOF
146 %left T_LPARN T_LBRACK T_STROP
149 %token <y_sb> T_TYPENAME
151 %token <y_strg> T_STRING
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
177 %type <y_sym> enumerator
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
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
214 /* empty translation unit */
217 /* empty translation unit */
226 | translation_unit ext_decl
243 /* syntax error: empty declaration */
246 /* syntax error: empty declaration */
250 | clrtyp deftyp notype_init_decls T_SEMI {
252 /* old style declaration; add "int" */
255 /* old style declaration; add "int" */
259 | declmods deftyp T_SEMI {
260 if (dcs->d_scl == TYPEDEF) {
261 /* typedef declares no type name */
264 /* empty declaration */
268 | declmods deftyp notype_init_decls T_SEMI
269 | declspecs deftyp T_SEMI {
270 if (dcs->d_scl == TYPEDEF) {
271 /* typedef declares no type name */
273 } else if (!dcs->d_nedecl) {
274 /* empty declaration */
278 | declspecs deftyp type_init_decls T_SEMI
289 if ($1->s_type->t_tspec != FUNC) {
294 if ($1->s_type->t_typedef) {
295 /* ()-less function definition */
302 } opt_arg_declaration_list {
314 clrtyp deftyp notype_decl {
317 | declmods deftyp notype_decl {
320 | declspecs deftyp type_decl {
325 opt_arg_declaration_list:
327 | arg_declaration_list
330 arg_declaration_list:
332 | arg_declaration_list arg_declaration
333 /* XXX or better "arg_declaration error" ? */
338 * "arg_declaration" is separated from "declaration" because it
339 * needs other error handling.
343 declmods deftyp T_SEMI {
344 /* empty declaration */
347 | declmods deftyp notype_init_decls T_SEMI
348 | declspecs deftyp T_SEMI {
349 if (!dcs->d_nedecl) {
350 /* empty declaration */
353 tspec_t ts = dcs->d_type->t_tspec;
354 /* %s declared in argument declaration list */
355 warning(3, ts == STRUCT ? "struct" :
356 (ts == UNION ? "union" : "enum"));
359 | declspecs deftyp type_init_decls T_SEMI {
361 tspec_t ts = dcs->d_type->t_tspec;
362 /* %s declared in argument declaration list */
363 warning(3, ts == STRUCT ? "struct" :
364 (ts == UNION ? "union" : "enum"));
372 declmods deftyp T_SEMI {
373 if (dcs->d_scl == TYPEDEF) {
374 /* typedef declares no type name */
377 /* empty declaration */
381 | declmods deftyp notype_init_decls T_SEMI
382 | declspecs deftyp T_SEMI {
383 if (dcs->d_scl == TYPEDEF) {
384 /* typedef declares no type name */
386 } else if (!dcs->d_nedecl) {
387 /* empty declaration */
391 | declspecs deftyp type_init_decls T_SEMI
411 | declmods typespec {
415 | declspecs notype_typespec {
440 clrtyp notype_typespec {
443 | T_TYPENAME clrtyp {
444 $$ = getsym($1)->s_type;
453 $$ = getsym($1)->s_type;
474 * STDC requires that "struct a;" always introduces
475 * a new tag if "a" is not declared at current level
477 * yychar is valid because otherwise the parser would
478 * not been able to deceide if he must shift or reduce
480 $$ = mktag($2, $1, 0, yychar == T_SEMI);
482 | struct struct_tag {
483 dcs->d_tagtyp = mktag($2, $1, 1, 0);
484 } struct_declaration {
485 $$ = compltag(dcs->d_tagtyp, $4);
488 dcs->d_tagtyp = mktag(NULL, $1, 1, 0);
489 } struct_declaration {
490 $$ = compltag(dcs->d_tagtyp, $3);
501 pushdecl($1 == STRUCT ? MOS : MOU);
503 dcs->d_stralign = CHAR_BIT;
515 struct_decl_lbrace member_declaration_list_with_rbrace {
526 member_declaration_list_with_rbrace:
527 member_declaration_list T_SEMI T_RBRACE {
530 | member_declaration_list T_RBRACE {
532 /* syntax req. ";" after last struct/union member */
535 /* syntax req. ";" after last struct/union member */
545 member_declaration_list:
549 | member_declaration_list T_SEMI member_declaration {
555 noclass_declmods deftyp {
556 /* too late, i know, but getsym() compensates it */
558 } notype_member_decls {
562 | noclass_declspecs deftyp {
564 } type_member_decls {
568 | noclass_declmods deftyp {
569 /* struct or union member must be named */
573 | noclass_declspecs deftyp {
574 /* struct or union member must be named */
588 | noclass_declmods typespec {
591 | noclass_declspecs T_QUAL {
594 | noclass_declspecs notype_typespec {
603 | noclass_declmods T_QUAL {
612 | notype_member_decls {
614 } T_COMMA type_member_decl {
615 $$ = lnklst($1, decl1str($4));
623 | type_member_decls {
625 } T_COMMA type_member_decl {
626 $$ = lnklst($1, decl1str($4));
634 | notype_decl T_COLON constant {
635 $$ = bitfield($1, toicon($3));
640 $$ = bitfield(NULL, toicon($3));
648 | type_decl T_COLON constant {
649 $$ = bitfield($1, toicon($3));
654 $$ = bitfield(NULL, toicon($3));
660 $$ = mktag($2, ENUM, 0, 0);
663 dcs->d_tagtyp = mktag($2, ENUM, 1, 0);
665 $$ = compltag(dcs->d_tagtyp, $4);
668 dcs->d_tagtyp = mktag(NULL, ENUM, 1, 0);
670 $$ = compltag(dcs->d_tagtyp, $3);
692 enum_decl_lbrace enums_with_opt_comma T_RBRACE {
704 enums_with_opt_comma:
710 /* trailing "," prohibited in enum declaration */
713 /* trailing "," prohibited in enum declaration */
724 | enums T_COMMA enumerator {
734 $$ = ename($1, enumval, 1);
736 | ename T_ASSIGN constant {
737 $$ = ename($1, toicon($3), 0);
750 | notype_init_decls T_COMMA type_init_decl
755 | type_init_decls T_COMMA type_init_decl
759 notype_decl opt_asm_spec {
763 | notype_decl opt_asm_spec {
765 } T_ASSIGN initializer {
771 type_decl opt_asm_spec {
775 | type_decl opt_asm_spec {
777 } T_ASSIGN initializer {
786 | pointer notype_direct_decl {
793 $$ = dname(getsym($1));
795 | T_LPARN type_decl T_RPARN {
798 | notype_direct_decl T_LBRACK T_RBRACK {
799 $$ = addarray($1, 0, 0);
801 | notype_direct_decl T_LBRACK constant T_RBRACK {
802 $$ = addarray($1, 1, toicon($3));
804 | notype_direct_decl param_list {
805 $$ = addfunc($1, $2);
815 | pointer type_direct_decl {
822 $$ = dname(getsym($1));
824 | T_LPARN type_decl T_RPARN {
827 | type_direct_decl T_LBRACK T_RBRACK {
828 $$ = addarray($1, 0, 0);
830 | type_direct_decl T_LBRACK constant T_RBRACK {
831 $$ = addarray($1, 1, toicon($3));
833 | type_direct_decl param_list {
834 $$ = addfunc($1, $2);
841 * param_decl and notype_param_decl exist to avoid a conflict in
842 * argument lists. A typename enclosed in parens should always be
843 * treated as a typename, not an argument.
844 * "typedef int a; f(int (a));" is "typedef int a; f(int foo(a));"
845 * not "typedef int a; f(int a);"
851 | pointer direct_param_decl {
858 $$ = dname(getsym($1));
860 | T_LPARN notype_param_decl T_RPARN {
863 | direct_param_decl T_LBRACK T_RBRACK {
864 $$ = addarray($1, 0, 0);
866 | direct_param_decl T_LBRACK constant T_RBRACK {
867 $$ = addarray($1, 1, toicon($3));
869 | direct_param_decl param_list {
870 $$ = addfunc($1, $2);
877 direct_notype_param_decl {
880 | pointer direct_notype_param_decl {
885 direct_notype_param_decl:
887 $$ = dname(getsym($1));
889 | T_LPARN notype_param_decl T_RPARN {
892 | direct_notype_param_decl T_LBRACK T_RBRACK {
893 $$ = addarray($1, 0, 0);
895 | direct_notype_param_decl T_LBRACK constant T_RBRACK {
896 $$ = addarray($1, 1, toicon($3));
898 | direct_notype_param_decl param_list {
899 $$ = addfunc($1, $2);
909 | asterisk type_qualifier_list {
910 $$ = mergepq($1, $2);
913 $$ = mergepq($1, $2);
915 | asterisk type_qualifier_list pointer {
916 $$ = mergepq(mergepq($1, $2), $3);
922 $$ = xcalloc(1, sizeof (pqinf_t));
931 | type_qualifier_list type_qualifier {
932 $$ = mergepq($1, $2);
938 $$ = xcalloc(1, sizeof (pqinf_t));
948 id_list_lparn identifier_list T_RPARN {
951 | abs_decl_param_list {
965 $$ = iname(getsym($1));
967 | identifier_list T_COMMA T_NAME {
968 $$ = lnklst($1, iname(getsym($3)));
970 | identifier_list error {
976 abs_decl_lparn T_RPARN {
979 | abs_decl_lparn vararg_parameter_type_list T_RPARN {
983 | abs_decl_lparn error T_RPARN {
995 vararg_parameter_type_list:
996 parameter_type_list {
999 | parameter_type_list T_COMMA T_ELLIPSE {
1005 /* ANSI C requires formal parameter before "..." */
1007 } else if (!tflag) {
1008 /* ANSI C requires formal parameter before "..." */
1016 parameter_type_list:
1017 parameter_declaration opt_asm_spec {
1020 | parameter_type_list T_COMMA parameter_declaration opt_asm_spec {
1021 $$ = lnklst($1, $3);
1025 parameter_declaration:
1027 $$ = decl1arg(aname(), 0);
1029 | declspecs deftyp {
1030 $$ = decl1arg(aname(), 0);
1032 | declmods deftyp notype_param_decl {
1033 $$ = decl1arg($3, 0);
1036 * param_decl is needed because of following conflict:
1037 * "typedef int a; f(int (a));" could be parsed as
1038 * "function with argument a of type int", or
1039 * "function with an abstract argument of type function".
1040 * This grammar realizes the second case.
1042 | declspecs deftyp param_decl {
1043 $$ = decl1arg($3, 0);
1045 | declmods deftyp abs_decl {
1046 $$ = decl1arg($3, 0);
1048 | declspecs deftyp abs_decl {
1049 $$ = decl1arg($3, 0);
1055 | T_ASM T_LPARN T_STRING T_RPARN {
1056 freeyyv(&$3, T_STRING);
1065 expr %prec T_COMMA {
1068 | init_lbrace init_expr_list init_rbrace
1069 | init_lbrace init_expr_list T_COMMA init_rbrace
1074 init_expr %prec T_COMMA
1075 | init_expr_list T_COMMA init_expr
1093 } abstract_declaration {
1099 abstract_declaration:
1100 noclass_declmods deftyp {
1101 $$ = decl1abs(aname());
1103 | noclass_declspecs deftyp {
1104 $$ = decl1abs(aname());
1106 | noclass_declmods deftyp abs_decl {
1109 | noclass_declspecs deftyp abs_decl {
1116 $$ = addptr(aname(), $1);
1121 | pointer direct_abs_decl {
1122 $$ = addptr($2, $1);
1127 T_LPARN abs_decl T_RPARN {
1130 | T_LBRACK T_RBRACK {
1131 $$ = addarray(aname(), 0, 0);
1133 | T_LBRACK constant T_RBRACK {
1134 $$ = addarray(aname(), 1, toicon($2));
1136 | direct_abs_decl T_LBRACK T_RBRACK {
1137 $$ = addarray($1, 0, 0);
1139 | direct_abs_decl T_LBRACK constant T_RBRACK {
1140 $$ = addarray($1, 1, toicon($3));
1142 | abs_decl_param_list {
1143 $$ = addfunc(aname(), $1);
1147 | direct_abs_decl abs_decl_param_list {
1148 $$ = addfunc($1, $2);
1171 identifier T_COLON {
1173 label(T_NAME, getsym($1), NULL);
1175 | T_CASE constant T_COLON {
1176 label(T_CASE, NULL, $2);
1179 | T_DEFAULT T_COLON {
1180 label(T_DEFAULT, NULL, NULL);
1186 compstmnt_lbrace declaration_list opt_stmnt_list compstmnt_rbrace
1187 | compstmnt_lbrace opt_stmnt_list compstmnt_rbrace
1217 | stmnt_list stmnt {
1220 | stmnt_list error T_SEMI {
1240 | if_without_else T_ELSE {
1245 | if_without_else T_ELSE error {
1248 | switch_expr stmnt {
1251 | switch_expr error {
1262 T_IF T_LPARN expr T_RPARN {
1269 T_SWITCH T_LPARN expr T_RPARN {
1279 | while_expr error {
1282 | do stmnt do_while_expr {
1298 T_WHILE T_LPARN expr T_RPARN {
1311 T_WHILE T_LPARN expr T_RPARN T_SEMI {
1317 T_FOR T_LPARN opt_expr T_SEMI opt_expr T_SEMI opt_expr T_RPARN {
1333 goto identifier T_SEMI {
1336 | goto error T_SEMI {
1339 | T_CONTINUE T_SEMI {
1348 | T_RETURN expr T_SEMI {
1360 T_ASM T_LPARN read_until_rparn T_SEMI {
1363 | T_ASM T_QUAL T_LPARN read_until_rparn T_SEMI {
1379 | declaration_list declaration {
1385 expr %prec T_COMMA {
1392 $$ = build(MULT, $1, $3);
1394 | expr T_DIVOP expr {
1395 $$ = build($2, $1, $3);
1397 | expr T_ADDOP expr {
1398 $$ = build($2, $1, $3);
1400 | expr T_SHFTOP expr {
1401 $$ = build($2, $1, $3);
1403 | expr T_RELOP expr {
1404 $$ = build($2, $1, $3);
1406 | expr T_EQOP expr {
1407 $$ = build($2, $1, $3);
1410 $$ = build(AND, $1, $3);
1413 $$ = build(XOR, $1, $3);
1416 $$ = build(OR, $1, $3);
1418 | expr T_LOGAND expr {
1419 $$ = build(LOGAND, $1, $3);
1421 | expr T_LOGOR expr {
1422 $$ = build(LOGOR, $1, $3);
1424 | expr T_QUEST expr T_COLON expr {
1425 $$ = build(QUEST, $1, build(COLON, $3, $5));
1427 | expr T_ASSIGN expr {
1428 $$ = build(ASSIGN, $1, $3);
1430 | expr T_OPASS expr {
1431 $$ = build($2, $1, $3);
1433 | expr T_COMMA expr {
1434 $$ = build(COMMA, $1, $3);
1443 /* XXX realy neccessary? */
1446 $$ = getnnode(getsym($1), yychar);
1452 $$ = getcnode(gettyp($1->v_tspec), $1);
1454 | T_LPARN expr T_RPARN {
1460 $$ = build($2 == INC ? INCAFT : DECAFT, $1, NULL);
1463 $$ = build($1 == INC ? INCBEF : DECBEF, $2, NULL);
1466 $$ = build(STAR, $2, NULL);
1469 $$ = build(AMPER, $2, NULL);
1472 $$ = build($1, $2, NULL);
1475 if (tflag && $1 == PLUS) {
1476 /* unary + is illegal in traditional C */
1479 $$ = build($1 == PLUS ? UPLUS : UMINUS, $2, NULL);
1481 | term T_LBRACK expr T_RBRACK {
1482 $$ = build(STAR, build(PLUS, $1, $3), NULL);
1484 | term T_LPARN T_RPARN {
1485 $$ = funccall($1, NULL);
1487 | term T_LPARN func_arg_list T_RPARN {
1488 $$ = funccall($1, $3);
1490 | term point_or_arrow T_NAME {
1493 /* XXX strmemb should be integrated in build() */
1495 /* must to this before strmemb is called */
1498 msym = strmemb($1, $2, getsym($3));
1499 $$ = build($2, $1, getnnode(msym, 0));
1504 | T_SIZEOF term %prec T_SIZEOF {
1505 if (($$ = $2 == NULL ? NULL : bldszof($2->tn_type)) != NULL)
1506 chkmisc($2, 0, 0, 0, 0, 0, 1);
1508 | T_SIZEOF T_LPARN type_name T_RPARN %prec T_SIZEOF {
1511 | T_LPARN type_name T_RPARN term %prec T_UNOP {
1520 | T_STRING string2 {
1521 $$ = catstrg($1, $2);
1528 /* concatenated strings are illegal in traditional C */
1533 | string2 T_STRING {
1534 $$ = catstrg($1, $2);
1539 expr %prec T_COMMA {
1540 $$ = funcarg(NULL, $1);
1542 | func_arg_list T_COMMA expr {
1543 $$ = funcarg($1, $3);
1576 * Gets a node for a constant and returns the value of this constant
1578 * Is the node not constant or too large for int or of type float,
1579 * a warning will be printed.
1581 * toicon() should be used only inside declarations. If it is used in
1582 * expressions, it frees the memory used for the expression.
1594 * Abstract declarations are used inside expression. To free
1595 * the memory would be a fatal error.
1597 if (dcs->d_ctx != ABSTRACT)
1600 if ((t = v->v_tspec) == FLOAT || t == DOUBLE || t == LDOUBLE) {
1602 /* integral constant expression expected */
1607 if ((u_quad_t)v->v_quad > INT_MAX) {
1608 /* integral constant too large */
1612 #ifdef XXX_BROKEN_GCC
1613 if (v->v_quad > INT_MAX) {
1614 /* integral constant too large */
1617 else if (v->v_quad < INT_MIN) {
1618 /* integral constant too large */
1622 if (v->v_quad > INT_MAX || v->v_quad < INT_MIN) {
1623 /* integral constant too large */
1634 idecl(sym_t *decl, int initflg)
1639 switch (dcs->d_ctx) {
1641 decl1ext(decl, initflg);
1644 (void)decl1arg(decl, initflg);
1647 decl1loc(decl, initflg);
1653 if (initflg && !initerr)
1658 * Discard all input tokens up to and including the next
1659 * unmatched right paren
1668 freeyyv(&yylval, yychar);
1671 while (yychar != T_RPARN || --level > 0) {
1672 if (yychar == T_LPARN) {
1674 } else if (yychar <= 0) {
1677 freeyyv(&yylval, yychar = yylex());