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 $
43 * Contains the level of current declaration. 0 is extern.
44 * Used for symbol table entries.
49 * level for memory allocation. Normaly the same as blklev.
50 * An exeption is the declaration of arguments in prototypes. Memory
51 * for these can't be freed after the declaration, but symbols must
52 * be removed from the symbol table after the declaration.
56 static int toicon __P((tnode_t *));
57 static void idecl __P((sym_t *, int));
58 static void ignuptorp __P((void));
77 %token T_LBRACE T_RBRACE T_LBRACK T_RBRACK T_LPARN T_RPARN
80 %token <y_op> T_INCDEC
85 %token <y_op> T_SHFTOP
91 %token <y_op> T_LOGAND
95 %token <y_op> T_ASSIGN
101 /* storage classes (extern, static, auto, register and typedef) */
102 %token <y_scl> T_SCLASS
104 /* types (char, int, short, long, unsigned, signed, float, double, void) */
105 %token <y_tspec> T_TYPE
107 /* qualifiers (const, volatile) */
108 %token <y_tqual> T_QUAL
110 /* struct or union */
111 %token <y_tspec> T_SOU
116 /* remaining keywords */
132 %right T_ASSIGN T_OPASS
133 %right T_QUEST T_COLON
144 %right T_UNOP T_INCDEC T_SIZEOF
145 %left T_LPARN T_LBRACK T_STROP
148 %token <y_sb> T_TYPENAME
150 %token <y_strg> T_STRING
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
176 %type <y_sym> enumerator
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
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
213 /* empty translation unit */
216 /* empty translation unit */
225 | translation_unit ext_decl
242 /* syntax error: empty declaration */
245 /* syntax error: empty declaration */
249 | clrtyp deftyp notype_init_decls T_SEMI {
251 /* old style declaration; add "int" */
254 /* old style declaration; add "int" */
258 | declmods deftyp T_SEMI {
259 if (dcs->d_scl == TYPEDEF) {
260 /* typedef declares no type name */
263 /* empty declaration */
267 | declmods deftyp notype_init_decls T_SEMI
268 | declspecs deftyp T_SEMI {
269 if (dcs->d_scl == TYPEDEF) {
270 /* typedef declares no type name */
272 } else if (!dcs->d_nedecl) {
273 /* empty declaration */
277 | declspecs deftyp type_init_decls T_SEMI
288 if ($1->s_type->t_tspec != FUNC) {
293 if ($1->s_type->t_typedef) {
294 /* ()-less function definition */
301 } opt_arg_declaration_list {
313 clrtyp deftyp notype_decl {
316 | declmods deftyp notype_decl {
319 | declspecs deftyp type_decl {
324 opt_arg_declaration_list:
326 | arg_declaration_list
329 arg_declaration_list:
331 | arg_declaration_list arg_declaration
332 /* XXX or better "arg_declaration error" ? */
337 * "arg_declaration" is separated from "declaration" because it
338 * needs other error handling.
342 declmods deftyp T_SEMI {
343 /* empty declaration */
346 | declmods deftyp notype_init_decls T_SEMI
347 | declspecs deftyp T_SEMI {
348 if (!dcs->d_nedecl) {
349 /* empty declaration */
352 tspec_t ts = dcs->d_type->t_tspec;
353 /* %s declared in argument declaration list */
354 warning(3, ts == STRUCT ? "struct" :
355 (ts == UNION ? "union" : "enum"));
358 | declspecs deftyp type_init_decls T_SEMI {
360 tspec_t ts = dcs->d_type->t_tspec;
361 /* %s declared in argument declaration list */
362 warning(3, ts == STRUCT ? "struct" :
363 (ts == UNION ? "union" : "enum"));
371 declmods deftyp T_SEMI {
372 if (dcs->d_scl == TYPEDEF) {
373 /* typedef declares no type name */
376 /* empty declaration */
380 | declmods deftyp notype_init_decls T_SEMI
381 | declspecs deftyp T_SEMI {
382 if (dcs->d_scl == TYPEDEF) {
383 /* typedef declares no type name */
385 } else if (!dcs->d_nedecl) {
386 /* empty declaration */
390 | declspecs deftyp type_init_decls T_SEMI
410 | declmods typespec {
414 | declspecs notype_typespec {
439 clrtyp notype_typespec {
442 | T_TYPENAME clrtyp {
443 $$ = getsym($1)->s_type;
452 $$ = getsym($1)->s_type;
473 * STDC requires that "struct a;" always introduces
474 * a new tag if "a" is not declared at current level
476 * yychar is valid because otherwise the parser would
477 * not been able to deceide if he must shift or reduce
479 $$ = mktag($2, $1, 0, yychar == T_SEMI);
481 | struct struct_tag {
482 dcs->d_tagtyp = mktag($2, $1, 1, 0);
483 } struct_declaration {
484 $$ = compltag(dcs->d_tagtyp, $4);
487 dcs->d_tagtyp = mktag(NULL, $1, 1, 0);
488 } struct_declaration {
489 $$ = compltag(dcs->d_tagtyp, $3);
500 pushdecl($1 == STRUCT ? MOS : MOU);
502 dcs->d_stralign = CHAR_BIT;
514 struct_decl_lbrace member_declaration_list_with_rbrace {
525 member_declaration_list_with_rbrace:
526 member_declaration_list T_SEMI T_RBRACE {
529 | member_declaration_list T_RBRACE {
531 /* syntax req. ";" after last struct/union member */
534 /* syntax req. ";" after last struct/union member */
544 member_declaration_list:
548 | member_declaration_list T_SEMI member_declaration {
554 noclass_declmods deftyp {
555 /* too late, i know, but getsym() compensates it */
557 } notype_member_decls {
561 | noclass_declspecs deftyp {
563 } type_member_decls {
567 | noclass_declmods deftyp {
568 /* struct or union member must be named */
572 | noclass_declspecs deftyp {
573 /* struct or union member must be named */
587 | noclass_declmods typespec {
590 | noclass_declspecs T_QUAL {
593 | noclass_declspecs notype_typespec {
602 | noclass_declmods T_QUAL {
611 | notype_member_decls {
613 } T_COMMA type_member_decl {
614 $$ = lnklst($1, decl1str($4));
622 | type_member_decls {
624 } T_COMMA type_member_decl {
625 $$ = lnklst($1, decl1str($4));
633 | notype_decl T_COLON constant {
634 $$ = bitfield($1, toicon($3));
639 $$ = bitfield(NULL, toicon($3));
647 | type_decl T_COLON constant {
648 $$ = bitfield($1, toicon($3));
653 $$ = bitfield(NULL, toicon($3));
659 $$ = mktag($2, ENUM, 0, 0);
662 dcs->d_tagtyp = mktag($2, ENUM, 1, 0);
664 $$ = compltag(dcs->d_tagtyp, $4);
667 dcs->d_tagtyp = mktag(NULL, ENUM, 1, 0);
669 $$ = compltag(dcs->d_tagtyp, $3);
691 enum_decl_lbrace enums_with_opt_comma T_RBRACE {
703 enums_with_opt_comma:
709 /* trailing "," prohibited in enum declaration */
712 /* trailing "," prohibited in enum declaration */
723 | enums T_COMMA enumerator {
733 $$ = ename($1, enumval, 1);
735 | ename T_ASSIGN constant {
736 $$ = ename($1, toicon($3), 0);
749 | notype_init_decls T_COMMA type_init_decl
754 | type_init_decls T_COMMA type_init_decl
758 notype_decl opt_asm_spec {
762 | notype_decl opt_asm_spec {
764 } T_ASSIGN initializer {
770 type_decl opt_asm_spec {
774 | type_decl opt_asm_spec {
776 } T_ASSIGN initializer {
785 | pointer notype_direct_decl {
792 $$ = dname(getsym($1));
794 | T_LPARN type_decl T_RPARN {
797 | notype_direct_decl T_LBRACK T_RBRACK {
798 $$ = addarray($1, 0, 0);
800 | notype_direct_decl T_LBRACK constant T_RBRACK {
801 $$ = addarray($1, 1, toicon($3));
803 | notype_direct_decl param_list {
804 $$ = addfunc($1, $2);
814 | pointer type_direct_decl {
821 $$ = dname(getsym($1));
823 | T_LPARN type_decl T_RPARN {
826 | type_direct_decl T_LBRACK T_RBRACK {
827 $$ = addarray($1, 0, 0);
829 | type_direct_decl T_LBRACK constant T_RBRACK {
830 $$ = addarray($1, 1, toicon($3));
832 | type_direct_decl param_list {
833 $$ = addfunc($1, $2);
840 * param_decl and notype_param_decl exist to avoid a conflict in
841 * argument lists. A typename enclosed in parens should always be
842 * treated as a typename, not an argument.
843 * "typedef int a; f(int (a));" is "typedef int a; f(int foo(a));"
844 * not "typedef int a; f(int a);"
850 | pointer direct_param_decl {
857 $$ = dname(getsym($1));
859 | T_LPARN notype_param_decl T_RPARN {
862 | direct_param_decl T_LBRACK T_RBRACK {
863 $$ = addarray($1, 0, 0);
865 | direct_param_decl T_LBRACK constant T_RBRACK {
866 $$ = addarray($1, 1, toicon($3));
868 | direct_param_decl param_list {
869 $$ = addfunc($1, $2);
876 direct_notype_param_decl {
879 | pointer direct_notype_param_decl {
884 direct_notype_param_decl:
886 $$ = dname(getsym($1));
888 | T_LPARN notype_param_decl T_RPARN {
891 | direct_notype_param_decl T_LBRACK T_RBRACK {
892 $$ = addarray($1, 0, 0);
894 | direct_notype_param_decl T_LBRACK constant T_RBRACK {
895 $$ = addarray($1, 1, toicon($3));
897 | direct_notype_param_decl param_list {
898 $$ = addfunc($1, $2);
908 | asterisk type_qualifier_list {
909 $$ = mergepq($1, $2);
912 $$ = mergepq($1, $2);
914 | asterisk type_qualifier_list pointer {
915 $$ = mergepq(mergepq($1, $2), $3);
921 $$ = xcalloc(1, sizeof (pqinf_t));
930 | type_qualifier_list type_qualifier {
931 $$ = mergepq($1, $2);
937 $$ = xcalloc(1, sizeof (pqinf_t));
947 id_list_lparn identifier_list T_RPARN {
950 | abs_decl_param_list {
964 $$ = iname(getsym($1));
966 | identifier_list T_COMMA T_NAME {
967 $$ = lnklst($1, iname(getsym($3)));
969 | identifier_list error {
975 abs_decl_lparn T_RPARN {
978 | abs_decl_lparn vararg_parameter_type_list T_RPARN {
982 | abs_decl_lparn error T_RPARN {
994 vararg_parameter_type_list:
995 parameter_type_list {
998 | parameter_type_list T_COMMA T_ELLIPSE {
1004 /* ANSI C requires formal parameter before "..." */
1006 } else if (!tflag) {
1007 /* ANSI C requires formal parameter before "..." */
1015 parameter_type_list:
1016 parameter_declaration opt_asm_spec {
1019 | parameter_type_list T_COMMA parameter_declaration opt_asm_spec {
1020 $$ = lnklst($1, $3);
1024 parameter_declaration:
1026 $$ = decl1arg(aname(), 0);
1028 | declspecs deftyp {
1029 $$ = decl1arg(aname(), 0);
1031 | declmods deftyp notype_param_decl {
1032 $$ = decl1arg($3, 0);
1035 * param_decl is needed because of following conflict:
1036 * "typedef int a; f(int (a));" could be parsed as
1037 * "function with argument a of type int", or
1038 * "function with an abstract argument of type function".
1039 * This grammar realizes the second case.
1041 | declspecs deftyp param_decl {
1042 $$ = decl1arg($3, 0);
1044 | declmods deftyp abs_decl {
1045 $$ = decl1arg($3, 0);
1047 | declspecs deftyp abs_decl {
1048 $$ = decl1arg($3, 0);
1054 | T_ASM T_LPARN T_STRING T_RPARN {
1055 freeyyv(&$3, T_STRING);
1064 expr %prec T_COMMA {
1067 | init_lbrace init_expr_list init_rbrace
1068 | init_lbrace init_expr_list T_COMMA init_rbrace
1073 init_expr %prec T_COMMA
1074 | init_expr_list T_COMMA init_expr
1092 } abstract_declaration {
1098 abstract_declaration:
1099 noclass_declmods deftyp {
1100 $$ = decl1abs(aname());
1102 | noclass_declspecs deftyp {
1103 $$ = decl1abs(aname());
1105 | noclass_declmods deftyp abs_decl {
1108 | noclass_declspecs deftyp abs_decl {
1115 $$ = addptr(aname(), $1);
1120 | pointer direct_abs_decl {
1121 $$ = addptr($2, $1);
1126 T_LPARN abs_decl T_RPARN {
1129 | T_LBRACK T_RBRACK {
1130 $$ = addarray(aname(), 0, 0);
1132 | T_LBRACK constant T_RBRACK {
1133 $$ = addarray(aname(), 1, toicon($2));
1135 | direct_abs_decl T_LBRACK T_RBRACK {
1136 $$ = addarray($1, 0, 0);
1138 | direct_abs_decl T_LBRACK constant T_RBRACK {
1139 $$ = addarray($1, 1, toicon($3));
1141 | abs_decl_param_list {
1142 $$ = addfunc(aname(), $1);
1146 | direct_abs_decl abs_decl_param_list {
1147 $$ = addfunc($1, $2);
1170 identifier T_COLON {
1172 label(T_NAME, getsym($1), NULL);
1174 | T_CASE constant T_COLON {
1175 label(T_CASE, NULL, $2);
1178 | T_DEFAULT T_COLON {
1179 label(T_DEFAULT, NULL, NULL);
1185 compstmnt_lbrace declaration_list opt_stmnt_list compstmnt_rbrace
1186 | compstmnt_lbrace opt_stmnt_list compstmnt_rbrace
1216 | stmnt_list stmnt {
1219 | stmnt_list error T_SEMI {
1239 | if_without_else T_ELSE {
1244 | if_without_else T_ELSE error {
1247 | switch_expr stmnt {
1250 | switch_expr error {
1261 T_IF T_LPARN expr T_RPARN {
1268 T_SWITCH T_LPARN expr T_RPARN {
1278 | while_expr error {
1281 | do stmnt do_while_expr {
1297 T_WHILE T_LPARN expr T_RPARN {
1310 T_WHILE T_LPARN expr T_RPARN T_SEMI {
1316 T_FOR T_LPARN opt_expr T_SEMI opt_expr T_SEMI opt_expr T_RPARN {
1332 goto identifier T_SEMI {
1335 | goto error T_SEMI {
1338 | T_CONTINUE T_SEMI {
1347 | T_RETURN expr T_SEMI {
1359 T_ASM T_LPARN read_until_rparn T_SEMI {
1362 | T_ASM T_QUAL T_LPARN read_until_rparn T_SEMI {
1378 | declaration_list declaration {
1384 expr %prec T_COMMA {
1391 $$ = build(MULT, $1, $3);
1393 | expr T_DIVOP expr {
1394 $$ = build($2, $1, $3);
1396 | expr T_ADDOP expr {
1397 $$ = build($2, $1, $3);
1399 | expr T_SHFTOP expr {
1400 $$ = build($2, $1, $3);
1402 | expr T_RELOP expr {
1403 $$ = build($2, $1, $3);
1405 | expr T_EQOP expr {
1406 $$ = build($2, $1, $3);
1409 $$ = build(AND, $1, $3);
1412 $$ = build(XOR, $1, $3);
1415 $$ = build(OR, $1, $3);
1417 | expr T_LOGAND expr {
1418 $$ = build(LOGAND, $1, $3);
1420 | expr T_LOGOR expr {
1421 $$ = build(LOGOR, $1, $3);
1423 | expr T_QUEST expr T_COLON expr {
1424 $$ = build(QUEST, $1, build(COLON, $3, $5));
1426 | expr T_ASSIGN expr {
1427 $$ = build(ASSIGN, $1, $3);
1429 | expr T_OPASS expr {
1430 $$ = build($2, $1, $3);
1432 | expr T_COMMA expr {
1433 $$ = build(COMMA, $1, $3);
1442 /* XXX realy neccessary? */
1445 $$ = getnnode(getsym($1), yychar);
1451 $$ = getcnode(gettyp($1->v_tspec), $1);
1453 | T_LPARN expr T_RPARN {
1459 $$ = build($2 == INC ? INCAFT : DECAFT, $1, NULL);
1462 $$ = build($1 == INC ? INCBEF : DECBEF, $2, NULL);
1465 $$ = build(STAR, $2, NULL);
1468 $$ = build(AMPER, $2, NULL);
1471 $$ = build($1, $2, NULL);
1474 if (tflag && $1 == PLUS) {
1475 /* unary + is illegal in traditional C */
1478 $$ = build($1 == PLUS ? UPLUS : UMINUS, $2, NULL);
1480 | term T_LBRACK expr T_RBRACK {
1481 $$ = build(STAR, build(PLUS, $1, $3), NULL);
1483 | term T_LPARN T_RPARN {
1484 $$ = funccall($1, NULL);
1486 | term T_LPARN func_arg_list T_RPARN {
1487 $$ = funccall($1, $3);
1489 | term point_or_arrow T_NAME {
1492 /* XXX strmemb should be integrated in build() */
1494 /* must to this before strmemb is called */
1497 msym = strmemb($1, $2, getsym($3));
1498 $$ = build($2, $1, getnnode(msym, 0));
1503 | T_SIZEOF term %prec T_SIZEOF {
1504 if (($$ = $2 == NULL ? NULL : bldszof($2->tn_type)) != NULL)
1505 chkmisc($2, 0, 0, 0, 0, 0, 1);
1507 | T_SIZEOF T_LPARN type_name T_RPARN %prec T_SIZEOF {
1510 | T_LPARN type_name T_RPARN term %prec T_UNOP {
1519 | T_STRING string2 {
1520 $$ = catstrg($1, $2);
1527 /* concatenated strings are illegal in traditional C */
1532 | string2 T_STRING {
1533 $$ = catstrg($1, $2);
1538 expr %prec T_COMMA {
1539 $$ = funcarg(NULL, $1);
1541 | func_arg_list T_COMMA expr {
1542 $$ = 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.
1595 * Abstract declarations are used inside expression. To free
1596 * the memory would be a fatal error.
1598 if (dcs->d_ctx != ABSTRACT)
1601 if ((t = v->v_tspec) == FLOAT || t == DOUBLE || t == LDOUBLE) {
1603 /* integral constant expression expected */
1608 if ((u_quad_t)v->v_quad > INT_MAX) {
1609 /* integral constant too large */
1613 #ifdef XXX_BROKEN_GCC
1614 if (v->v_quad > INT_MAX) {
1615 /* integral constant too large */
1618 else if (v->v_quad < INT_MIN) {
1619 /* integral constant too large */
1623 if (v->v_quad > INT_MAX || v->v_quad < INT_MIN) {
1624 /* integral constant too large */
1635 idecl(decl, initflg)
1642 switch (dcs->d_ctx) {
1644 decl1ext(decl, initflg);
1647 (void)decl1arg(decl, initflg);
1650 decl1loc(decl, initflg);
1656 if (initflg && !initerr)
1661 * Discard all input tokens up to and including the next
1662 * unmatched right paren
1671 freeyyv(&yylval, yychar);
1674 while (yychar != T_RPARN || --level > 0) {
1675 if (yychar == T_LPARN) {
1677 } else if (yychar <= 0) {
1680 freeyyv(&yylval, yychar = yylex());